コード例 #1
0
    def handle(self, *args, **options):
        if options['blacklist']:
            self.resolve_blacklist()
            return

        while True:
            try:
                # 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'],
                    MaxNumberOfMessages=1,
                )

                messages = response.get('Messages')
                if not messages:
                    continue

                # There is only ever 1 because MaxNumberOfMessages=1
                message = Message.from_event(messages[0])

                already_deduplicated = redis_client.get(message.message_deduplication_id)
                if already_deduplicated and already_deduplicated.decode('UTF-8') == 'True':
                    self.remove_from_queue(message)
                    continue

                # If someone uploads a data hash that is faulty, then we want to blacklist all events around that
                # bounty id. It can either be a permanent blacklist, typically added manually, or a pending blacklist.
                # All the events in the pending blacklist will retry later.
                permanent_blacklist = redis_client.get('blacklist:{}'.format(message.bounty_id))
                pending_blacklist = redis_client.exists('pending_blacklist:{}'.format(message.bounty_id))

                if permanent_blacklist or pending_blacklist:
                    self.remove_from_queue(message)
                    if permanent_blacklist:
                        logger.info('Skipping event for {}, permanent blacklist found'.format(message.bounty_id))
                    else:
                        logger.info('Pending blacklist exists for {}, adding event {}'.format(message.bounty_id, message.event))
                        self.add_to_blacklist(message)
                    continue

                self.handle_message(message)
                self.remove_from_queue(message)

            except Exception as e:
                # goes to rollbar
                logger.error(e)
                self.remove_from_queue(message)
                self.add_to_blacklist(message)
コード例 #2
0
    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
コード例 #3
0
    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