Bogdanp / django_dramatiq

A Django app that integrates with Dramatiq.
https://dramatiq.io
Other
331 stars 77 forks source link

Configuring CurrentMessage with RabbitMQ as the broker? #125

Closed mojomojomojo closed 1 year ago

mojomojomojo commented 1 year ago

_(Django 4.0.2; Dramatiq 1.13, djangodramatiq 0.11.0)

Rather than configure a results backend, I want to save results directly to an extant db backend used by django, keyed by the message ID. It sounds like the CurrentMessage middleware could provide this information to the dramatiq.actor task.

@dramatiq.actor(time_limit=10_000,throws=(Exception,))
def count_so():
    print(CurrentMessage.get_current_message())
    ....

When I invoke this, (e.g. s = count_so.send()), I don't get what I expect. count_so() I was expecting something that looked a lot more like the message return from .send() (at least containing the UUID). Message(queue_name='default', actor_name='count_so', args=(), kwargs={}, options={}, message_id='418377a0-6e3d-4f5d-96f1-45f415d2fcad', message_timestamp=1666790194865)

Perhaps I'm configuring the broker/middleware incorrectly?

Do I need to do more than this (settings.py)

DRAMATIQ_BROKER = {
    ...
    "MIDDLEWARE": [
        ...
        "dramatiq.middleware.CurrentMessage",
        ...
    ]
}

I'm using RabbitMQ as the broker. The dramatiq docs don't specifically say how to configure it with Django. Do I need to do all the things listed in the ReadMe ("Custom keyword arguments to Middleware")?

Am I doing something else wrong, or should I not expect to see the message ID?

Bogdanp commented 1 year ago

Messages have a custom __str__ method that makes their printed output look like the function application that invoked them: https://github.com/Bogdanp/dramatiq/blob/b1100b6584a71a2aaf42b4cf7f0e36ca7f35c0ef/dramatiq/message.py#L157-L163

Using repr would probably have shown you what you expected:

print(repr(CurrentMessage.get_current_message()))

At any rate, I think you probably are getting the current message, so you should be able to access its id just fine. I.e. this should also work:

print(CurrentMessage.get_current_message().message_id)
mojomojomojo commented 1 year ago

Thanks. That worked. I had attempted to

msg = CurrentMessage.get_current_message()
print(msg.__dict__)
print(dir(msg))

neither of which showed my the attributes I was looking for.

Is there a way to discover what attributes an object actually has?

Bogdanp commented 1 year ago

They are documented here: https://dramatiq.io/reference.html#dramatiq.Message . Every parameter is also a field on each message.