def remove_from_queue(self, message): # This means the contract subscriber will never send this event # through to sqs again redis_client.set(message.message_deduplication_id, 'True') try: sqs_client.delete_message( QueueUrl=settings.QUEUE_URL, ReceiptHandle=message.receipt_handle, ) except ClientError as e: logger.warning('SQS delete_message hit an error: '.format(e.response['Error']['Message']))
def handle(self, *args, **options): try: while True: # poll by the second if not settings.LOCAL: time.sleep(1) # TODO - All should be a transaction atomic function response = sqs_client.receive_message( QueueUrl=settings.QUEUE_URL, AttributeNames=['MessageDeduplicationId'], MessageAttributeNames=['All'], ) messages = response.get('Messages') if not messages: continue message = messages[0] receipt_handle = message['ReceiptHandle'] message_attributes = message['MessageAttributes'] event = message_attributes['Event']['StringValue'] bounty_id = int(message_attributes['BountyId']['StringValue']) fulfillment_id = int( message_attributes['FulfillmentId']['StringValue']) message_deduplication_id = message_attributes[ 'MessageDeduplicationId']['StringValue'] transaction_from = message_attributes['TransactionFrom'][ 'StringValue'] transaction_hash = message_attributes['TransactionHash'][ 'StringValue'] event_timestamp = message_attributes['TimeStamp'][ 'StringValue'] contract_method_inputs = json.loads( message_attributes['ContractMethodInputs']['StringValue']) event_date = datetime.datetime.fromtimestamp( int(event_timestamp)) # If someone uploads a data hash that is faulty, then we want to blacklist all events around that # bounty id. We manage this manually if redis_client.get('blacklist:' + str(bounty_id)): redis_client.set(message_deduplication_id, True) sqs_client.delete_message( QueueUrl=settings.QUEUE_URL, ReceiptHandle=receipt_handle, ) continue logger.info('attempting {}: for bounty id {}'.format( event, str(bounty_id))) if event == 'BountyIssued': master_client.bounty_issued( bounty_id, event_date=event_date, inputs=contract_method_inputs, event_timestamp=event_timestamp) if event == 'BountyActivated': master_client.bounty_activated( bounty_id, event_date=event_date, inputs=contract_method_inputs, event_timestamp=event_timestamp) if event == 'BountyFulfilled': master_client.bounty_fulfilled( bounty_id, fulfillment_id=fulfillment_id, event_date=event_date, inputs=contract_method_inputs, event_timestamp=event_timestamp, transaction_issuer=transaction_from) if event == 'FulfillmentUpdated': master_client.fullfillment_updated( bounty_id, event_date=event_date, fulfillment_id=fulfillment_id, inputs=contract_method_inputs) if event == 'FulfillmentAccepted': master_client.fulfillment_accepted( bounty_id, event_date=event_date, fulfillment_id=fulfillment_id, event_timestamp=event_timestamp) if event == 'BountyKilled': master_client.bounty_killed( bounty_id, event_date=event_date, event_timestamp=event_timestamp) if event == 'ContributionAdded': master_client.contribution_added( bounty_id, event_date=event_date, inputs=contract_method_inputs, event_timestamp=event_timestamp) if event == 'DeadlineExtended': master_client.deadline_extended( bounty_id, event_date=event_date, inputs=contract_method_inputs, event_timestamp=event_timestamp) if event == 'BountyChanged': master_client.bounty_changed(bounty_id, event_date=event_date, inputs=contract_method_inputs) if event == 'IssuerTransferred': master_client.issuer_transferred( bounty_id, transaction_from=transaction_from, event_date=event_date, inputs=contract_method_inputs) if event == 'PayoutIncreased': master_client.payout_increased( bounty_id, event_date=event_date, inputs=contract_method_inputs) logger.info(event) # This means the contract subscriber will never send this event # through to sqs again Event.objects.get_or_create( event=event, transaction_hash=transaction_hash, defaults={ 'bounty_id': bounty_id, 'fulfillment_id': fulfillment_id if fulfillment_id != -1 else None, 'transaction_from': transaction_from, 'contract_inputs': contract_method_inputs, 'event_date': event_date, }) redis_client.set(message_deduplication_id, True) sqs_client.delete_message( QueueUrl=settings.QUEUE_URL, ReceiptHandle=receipt_handle, ) except Exception as e: # goes to rollbar logger.exception(e) raise e
def handle(self, *args, **options): try: bounty_client = BountyClient() sc = SlackClient(settings.SLACK_TOKEN) while True: # poll by the second if not settings.LOCAL: time.sleep(1) response = sqs_client.receive_message( QueueUrl=settings.QUEUE_URL, AttributeNames=['MessageDeduplicationId'], MessageAttributeNames=['All'], ) messages = response.get('Messages') if not messages: continue message = messages[0] receipt_handle = message['ReceiptHandle'] message_attributes = message['MessageAttributes'] event = message_attributes['Event']['StringValue'] bounty_id = int(message_attributes['BountyId']['StringValue']) fulfillment_id = int( message_attributes['FulfillmentId']['StringValue']) message_deduplication_id = message_attributes[ 'MessageDeduplicationId']['StringValue'] transaction_from = message_attributes['TransactionFrom'][ 'StringValue'] event_timestamp = message_attributes['TimeStamp'][ 'StringValue'] contract_method_inputs = json.loads( message_attributes['ContractMethodInputs']['StringValue']) # If someone uploads a data hash that is faulty, then we want to blacklist all events around that # bounty id. We manage this manually if redis_client.get('blacklist:' + str(bounty_id)): redis_client.set(message_deduplication_id, True) sqs_client.delete_message( QueueUrl=settings.QUEUE_URL, ReceiptHandle=receipt_handle, ) continue logger.info('attempting {}: for bounty id {}'.format( event, str(bounty_id))) if event == 'BountyIssued': bounty_client.issue_bounty(bounty_id, contract_method_inputs, event_timestamp) if event == 'BountyActivated': bounty_client.activate_bounty(bounty_id, contract_method_inputs) if event == 'BountyFulfilled': bounty_client.fulfill_bounty(bounty_id, fulfillment_id, contract_method_inputs, event_timestamp, transaction_from) if event == 'FulfillmentUpdated': bounty_client.update_fulfillment(bounty_id, fulfillment_id, contract_method_inputs) if event == 'FulfillmentAccepted': bounty_client.accept_fulfillment(bounty_id, fulfillment_id) if event == 'BountyKilled': bounty_client.kill_bounty(bounty_id) if event == 'ContributionAdded': bounty_client.add_contribution(bounty_id, contract_method_inputs) if event == 'DeadlineExtended': bounty_client.extend_deadline(bounty_id, contract_method_inputs) if event == 'BountyChanged': bounty_client.change_bounty(bounty_id, contract_method_inputs) if event == 'IssuerTransferred': bounty_client.transfer_issuer(bounty_id, contract_method_inputs) if event == 'PayoutIncreased': bounty_client.increase_payout(bounty_id, contract_method_inputs) logger.info(event) # We should create a separate client to manage these # notifications to slack sc.api_call('chat.postMessage', channel=settings.NOTIFICATIONS_SLACK_CHANNEL, text='Event {} passed for bounty {}'.format( event, str(bounty_id))) # This means the contract subscriber will never send this event # through to sqs again redis_client.set(message_deduplication_id, True) sqs_client.delete_message( QueueUrl=settings.QUEUE_URL, ReceiptHandle=receipt_handle, ) except Exception as e: # goes to rollbar logger.exception(e) raise e