czue / celery-progress

Drop in, configurable, dependency-free progress bars for your Django/Celery applications.
MIT License
473 stars 90 forks source link

How would one use this progress bar when a task is wrapped in a Django transaction.on_commit? #84

Open pmi123 opened 3 years ago

pmi123 commented 3 years ago

Your usage notes for the view depends on the task returning a task_id:

def progress_view(request):
    result = my_task.delay(10)
    return render(request, 'display_progress.html', context={'task_id': result.task_id})

but a transaction.on_commit does not return a task_id, since the task may not have started yet. Any suggestions on how to use your progress bar with transactions?

Thanks! Mark

OmarWKH commented 3 years ago

To overcome this, I gave the task a custom id.

pmi123 commented 3 years ago

Could you elaborate a little more on how you got it to work?

Thanks!

Mark

OmarWKH commented 3 years ago

I didn't run this code. But it gives you the general idea.

# pre-generate a random id
custom_id = celery.utils.gen_unique_id()

# set task id to custom id
task_function = lambda: my_task.apply_async(args, task_id=custom_id)

# instead of passing my_task.apply_async directly, it's wrapped in a lambda function so we can give it arguments
transaction.on_commit(task_function)
pmi123 commented 3 years ago

Thanks!

Giving a task a custom task_id is a new concept for me. While we were talking, I implemented my progress bar using my Django site's MySQL db and uuid.uuid4().hex to generate a unique ID outside of the celery task, but I will take a look at using this approach when I have some free time. Yours will certainly be more efficient than periodically hitting the db to get the progress amount in my view. But, it does work!

Mark