Skip to content

Instantly share code, notes, and snippets.

@Geekfish
Last active January 7, 2019 14:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Geekfish/89bd75dc38a7a5aed64c6bede29f7ca4 to your computer and use it in GitHub Desktop.
Save Geekfish/89bd75dc38a7a5aed64c6bede29f7ca4 to your computer and use it in GitHub Desktop.
DjangoRQ Transaction aware job decorator
from jobs import send_welcome_email
# ...
def register_user():
user = do_the_registration()
send_welcome_email.transaction_aware_delay(user.id)
# or
# send_welcome_email.request_aware_delay(user.id)
# ...
from django_rq import job
from my_decorators import with_request_aware_delay
# ...
# Example use:
@with_request_aware_delay
@job('high')
def send_welcome_email(user_id):
send_the_email(user_id)
# OR
@with_transaction_aware_delay
@job('high')
def send_welcome_email(user_id):
send_the_email(user_id)
# ...
from django.core.signals import request_finished
from django.db import transaction
def with_request_aware_delay(job_func):
# Warning: request_finished doesn't fire properly on some wsgi servers.
# Replace this with on_commit on upgrade to Django 1.9.
def request_aware_delay(*args, **kwargs):
def do_delay(*receiver_args, **receiver_kwargs):
try:
job_func.delay(*args, **kwargs)
except Exception:
raise
finally:
# Disconnect the receiver, in case for whatever reason the signal is triggered again.
request_finished.disconnect(receiver=do_delay, weak=False)
request_finished.connect(receiver=do_delay, weak=False)
job_func.request_aware_delay = request_aware_delay
return job_func
# From Django 1.9 onwards you can use this instead:
def with_transaction_aware_delay(job_func):
def transaction_aware_delay(*args, **kwargs):
def do_delay():
job_func.delay(*args, **kwargs)
transaction.on_commit(do_delay)
job_func.transaction_aware_delay = transaction_aware_delay
return job_func
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment