Exemple #1
0
    def post_delete(cls, sender, **kwargs):
        """
        :param dj_cqrs.mixins.MasterMixin sender: Class or instance inherited from CQRS MasterMixin.
        """
        if not sender.CQRS_PRODUCE:
            return

        instance = kwargs['instance']
        if not instance.is_sync_instance():
            return

        instance_data = {
            'id': instance.pk,
            'cqrs_revision': instance.cqrs_revision + 1,
            'cqrs_updated': str(now()),
        }

        data = instance.get_custom_cqrs_delete_data()
        if data:
            instance_data['custom'] = data

        signal_type = SignalType.DELETE

        payload = TransportPayload(
            signal_type,
            sender.CQRS_ID,
            instance_data,
            instance.pk,
            expires=get_expires_datetime(),
        )
        # Delete is always in transaction!
        transaction.on_commit(lambda: producer.produce(payload))
Exemple #2
0
    def from_message(cls, dct):
        """Builds payload from message data.

        :param dct: Deserialized message body data.
        :type dct: dict
        :return: TransportPayload instance.
        :rtype: TransportPayload
        """
        if 'expires' in dct:
            expires = dct['expires']
            if dct['expires'] is not None:
                expires = dateutil_parse(dct['expires'])
        else:
            # Backward compatibility for old messages otherwise they are infinite by default.
            expires = get_expires_datetime()

        return cls(
            dct['signal_type'],
            dct['cqrs_id'],
            dct['instance_data'],
            dct.get('instance_pk'),
            previous_data=dct.get('previous_data'),
            correlation_id=dct.get('correlation_id'),
            expires=expires,
            retries=dct.get('retries') or 0,
        )
Exemple #3
0
def test_get_expires_datetime_infinite(mocker, settings):
    settings.CQRS['master']['CQRS_MESSAGE_TTL'] = None
    fake_now = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc)
    mocker.patch('django.utils.timezone.now', return_value=fake_now)

    result = get_expires_datetime()

    assert result is None
Exemple #4
0
def test_get_expires_datetime(mocker, settings):
    settings.CQRS['master']['CQRS_MESSAGE_TTL'] = 3600
    fake_now = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc)
    mocker.patch('django.utils.timezone.now', return_value=fake_now)

    result = get_expires_datetime()

    expected_result = fake_now + timedelta(seconds=3600)
    assert result == expected_result
Exemple #5
0
    def post_save(cls, sender, **kwargs):
        """
        :param dj_cqrs.mixins.MasterMixin sender: Class or instance inherited from CQRS MasterMixin.
        """
        if not sender.CQRS_PRODUCE:
            return

        update_fields = kwargs.get('update_fields')
        if update_fields and ('cqrs_revision' not in update_fields):
            return

        instance = kwargs['instance']
        if not instance.is_sync_instance():
            return

        using = kwargs['using']

        sync = kwargs.get('sync', False)
        queue = kwargs.get('queue', None)

        connection = transaction.get_connection(using)
        if not connection.in_atomic_block:
            instance.reset_cqrs_saves_count()
            instance_data = instance.to_cqrs_dict(using, sync=sync)
            previous_data = instance.get_tracked_fields_data()
            signal_type = SignalType.SYNC if sync else SignalType.SAVE
            payload = TransportPayload(
                signal_type,
                sender.CQRS_ID,
                instance_data,
                instance.pk,
                queue,
                previous_data,
                expires=get_expires_datetime(),
            )
            producer.produce(payload)

        elif instance.is_initial_cqrs_save:
            transaction.on_commit(
                lambda: MasterSignals.post_save(
                    sender,
                    instance=instance,
                    using=using,
                    sync=sync,
                    queue=queue,
                ), )
    def handle_retry(self, channel, consumer_generator, dead_letters_count):
        self.stdout.write("Total dead letters: {}".format(dead_letters_count))
        for i in range(1, dead_letters_count + 1):
            self.stdout.write("Retrying: {}/{}".format(i, dead_letters_count))
            method_frame, properties, body = next(consumer_generator)

            dct = ujson.loads(body)
            dct['retries'] = 0
            if dct.get('expires'):
                # Message could expire already
                expires = get_expires_datetime()
                dct['expires'] = expires.replace(microsecond=0).isoformat()
            payload = TransportPayload.from_message(dct)
            payload.is_requeue = True

            RabbitMQTransportService.produce(payload)
            message = ujson.dumps(dct)
            self.stdout.write(message)

            RabbitMQTransportService.nack(channel, method_frame.delivery_tag)