amichib amichib - 10 months ago 54
Python Question

run celery tasks in random times

i need to run few celery tasks in random times - every run should be at a new random time - the random number should generated every run.

what I did in the past is:

"my_task": {
"task": "",
"schedule": crontab(minute='*/%s' % rand),
rand = random(1,12)

but this code is not good for my needs anu more:

1. I need different (as possible with random0 number for each tenant

2. different number will generated every time and not only on load (once)

I tried to overwrite Schedule as explained in THIS answer but it did not work, is there better way? am I missing something?

(for example in tenant A the task will run at 23 and the day after at 8, and in tenant B the task will run at 4 and the day after at 20 etc)


======== update ====

after the great answer I got, I added option to my task and process it in apply_asynch method as suggested-

"my-task": { # deprecated task
"task": "mdm_sync.tasks.test_task",
# "schedule": new_sc(),
"schedule": crontab(minute=39, hour=11),
"options": {
"eta": datetime.utcnow()

entry.options["eta"] = datetime.datetime.utcnow() + datetime.timedelta(seconds=random(3600,12*3600)

works great!

Answer Source

I faced a similar problem in which i had to generate facebook like notifications between random users at random interval of time

Initially i was also doing the same as you, using the random function to give the minute value to crontab. But, as and are loaded only once when you hit python runserver, that random function runs only once and hence that random value is selected only once, say 5 minutes or 7 minutes, but then this random value is used for repeating the task at every 5 or 7 minutes, hence making the tasks repeat periodically.

So, what you need to do is that instead of defining the timing of task in or you need to recursively call the function/ method in your But the key here is that you need to call the same function recursively and asynchronously, and while calling it asynchronously, you need to pass a parameter delay whose value will be calculated by using the random function

See my ->

And ->

You'll have to python shell and then call the function / method from there only once to start the recursion.

something like


In my case it used to be