class BatchSubmitter: def __init__(self, timeout): self.batches = [] self.imf = IntkeyMessageFactory() self.timeout = timeout def _post_batch(self, batch): headers = {'Content-Type': 'application/octet-stream'} response = self._query_rest_api('/batches?wait={}'.format( self.timeout), data=batch, headers=headers) return response def _query_rest_api(self, suffix='', data=None, headers={}): url = 'http://rest-api:8080' + suffix request = urllib.request.Request(url, data, headers) response = urllib.request.urlopen(request).read().decode('utf-8') return json.loads(response) def make_batch(self, n): return self.imf.create_batch([('set', str(n), 0)]) def submit_next_batch(self): batch_list_bytes = self.make_batch(len(self.batches)) batch_list = batch_pb2.BatchList() batch_list.ParseFromString(batch_list_bytes) self.batches.append(batch_list.batches[0]) self._post_batch(batch_list_bytes) return len(self.batches) - 1
class BatchSubmitter: def __init__(self): self.n = 0 self.imf = IntkeyMessageFactory() def _post_batch(self, batch): headers = {'Content-Type': 'application/octet-stream'} response = self._query_rest_api('/batches', data=batch, headers=headers) return response def _query_rest_api(self, suffix='', data=None, headers={}): url = 'http://rest-api:8080' + suffix request = urllib.request.Request(url, data, headers) response = urllib.request.urlopen(request).read().decode('utf-8') return json.loads(response) def make_batch(self, n): return self.imf.create_batch([('set', str(n), 0)]) def submit_next_batch(self): batch = self.make_batch(self.n) self.n += 1 self._post_batch(batch) time.sleep(0.5)
class IntkeyClient(RestClient): def __init__(self, url, wait=30): super().__init__(url) self.url = url self.factory = IntkeyMessageFactory() self.wait = wait def send_txns(self, txns): batch = self.factory.create_batch(txns) attempts = 0 response = None while True: try: response = self.send_batches(batch) id_query = urlparse(response['link']).query return parse_qs(id_query)['id'][0] except CliException: if attempts < 8: LOGGER.info('responding to back-pressure, retrying...') attempts += 1 time.sleep(0.2 * (2 ** attempts)) else: raise def recent_block_signatures(self, tolerance): return self.list_block_signatures()[:tolerance] def list_block_signatures(self): return [block['header_signature'] for block in self.list_blocks()] def calculate_tolerance(self): length = len(list(self.list_blocks())) # the most recent nth of the chain, at least 2 blocks return max(2, length // 5) def poll_for_batches(self, batch_ids): """Poll timeout seconds for a batch status to become non-pending Args: batch_id (str): The id to get the status of """ time_waited = 0 start_time = time.time() while time_waited < self.wait: res = self._get( '/batch_statuses', id=','.join(batch_ids), wait=(self.wait - time_waited)) if 'PENDING' not in [data['status'] for data in res['data']]: return time_waited = time.time() - start_time raise RestClientException( 'Request timed out after %d seconds' % self.wait)
class BatchSubmitter: def __init__(self, timeout): self.batches = [] self.imf = IntkeyMessageFactory() self.timeout = timeout wait_for_rest_apis(['rest-api:8008']) def _post_batch(self, batch): headers = {'Content-Type': 'application/octet-stream'} response = self._query_rest_api( '/batches', data=batch, headers=headers, expected_code=202) return self._submit_request('{}&wait={}'.format( response['link'], self.timeout)) def _query_rest_api(self, suffix='', data=None, headers=None, expected_code=200): if headers is None: headers = {} url = 'http://rest-api:8008' + suffix return self._submit_request(urllib.request.Request(url, data, headers), expected_code=expected_code) def _submit_request(self, request, expected_code=200): conn = urllib.request.urlopen(request) assert expected_code == conn.getcode() response = conn.read().decode('utf-8') return json.loads(response) def make_batch(self, num): return self.imf.create_batch([('set', str(num), 0)]) def submit_next_batch(self): batch_list_bytes = self.make_batch(len(self.batches)) batch_list = batch_pb2.BatchList() batch_list.ParseFromString(batch_list_bytes) self.batches.append(batch_list.batches[0]) self._post_batch(batch_list_bytes) return len(self.batches) - 1
class IntkeyClient(RestClient): def __init__(self, url): super().__init__(url) self.url = url self.factory = IntkeyMessageFactory() def send_txns(self, txns): batch = self.factory.create_batch(txns) self.send_batches(batch) def recent_block_signatures(self, tolerance): signatures = self.list_block_signatures() return self.list_block_signatures()[:tolerance] def list_block_signatures(self): return [block['header_signature'] for block in self.list_blocks()] def calculate_tolerance(self): length = len(self.list_blocks()) # the most recent nth of the chain, at least 2 blocks return max(2, length // 5)
class IntkeyClient(RestClient): def __init__(self, url): super().__init__(url) self.url = url self.factory = IntkeyMessageFactory() def send_txns(self, txns): batch = self.factory.create_batch(txns) self.send_batches(batch) def recent_block_signatures(self, tolerance): signatures = self.list_block_signatures() return self.list_block_signatures()[:tolerance] def list_block_signatures(self): return [block['header_signature'] for block in self.list_blocks()] def calculate_tolerance(self): length = len(self.list_blocks()) # the most recent nth of the chain, at least 2 blocks return max( 2, length // 5)
def make_batches(keys): imf = IntkeyMessageFactory() return [imf.create_batch([('set', k, 0)]) for k in keys]