Pergunta

I've been coding the python "apscheduler" package (Advanced Python Scheduler) into my app, so far it's going good, I'm able to do almost everything that I had envisioned doing with it.

Only one kink left to iron out...

The function my events are calling will only accept around 3 calls a second or fail as it is triggering very slow hardware I/O :(

I've tried limiting the max number of threads in the threadpool from 20 to just 1 to try and slow down execution, but since I'm not really putting a bit load on apscheduler my events are still firing pretty much concurrently (well... very, very close together at least).

Is there a way to 'stagger' different events that fire within the same second?

Foi útil?

Solução 4

My solution for future reference:

I added a basic bool lock in the function being called and a wait which seems to do the trick nicely - since it's not the calling of the function itself that raises the error, but rather a deadlock situation with what the function carries out :D

Outras dicas

What you want to use is the 'jitter' option.

From the docs:

The jitter option enables you to add a random component to the execution time. This might be useful if you have multiple servers and don’t want them to run a job at the exact same moment or if you want to prevent multiple jobs with similar options from always running concurrently

Example:

# Run the `job_function` every hour with an extra-delay picked randomly 
# in a [-120,+120] seconds window.
sched.add_job(job_function, 'interval', hours=1, jitter=120)

I have recently found this question because I, like yourself, was trying to stagger scheduled jobs slightly to compensate for slow hardware.

Including an argument like this in the scheduler add_job call staggers the start time for each job by 200ms (while incrementing idx for each job):

next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=idx * 0.2)

I don't know about apscheduler but have you considered using a Redis LIST (queue) and simply serializing the event feed into that one critically bounded function so that it fires no more than three times per second? (For example you could have it do a blocking POP with a one second max delay, increment your trigger count for every event, sleep when it hits three, and zero the trigger count any time the blocking POP times out (Or you could just use 333 millisecond sleeps after each event).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top