Is it possible to enqueue an instance method, as opposed to a function, using Python-RQ?

Question:

The examples provided in the Python-RQ documentation consistently show functions being enqueued, using queue.enqueue(). For example:

job = q.enqueue(count_words_at_url, 'http://nvie.com')

Is it possible to enqueue a method of a particular object instance? And if so, is this considered reasonable practise?

For example:

member = Member.objects.get(id=142)
job = q.enqueue(member.send_email())

If the answer to either of the above questions is no, what is the reccommended pattern to approach this situation?

One possiblity I had considered was to create a helper function, that is independent of the Member model. For example:

def send_member_email_bg_task(member_id):
    Member.objects.get(id=member_id).send_email()

and enqueue it as follows:

job = q.enqueue(send_member_email_bg_task, member.id)

I would be grateful for suggestions on the best way to approach this.
Thanks

Asked By: Scratcha

||

Answers:

You can enqueue any queueable object. In this case, that object is the bound method member.send_mail, not the object that results from the call member.send_email().

member = Member.objects.get(id=142)
job = q.enqueue(member.send_email)

The bound method produced by member.send_email wraps both member and type(member).send_email, and when called calls the wrapped function with member as its first argument.

Answered By: chepner