New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sched doesn't handle at the expected time those events which are added after scheduler starts #64325
Comments
Events added after the scheduler is running, with a delay value before the next event, do not run at the correct time. import sched
import time
import threading
def event( eventNum ):
print( 'event', eventNum, time.time() )
s = sched.scheduler()
s.enter( 0,1,event, (0,) )
s.enter(10,1,event, (1,) )
t = threading.Thread( target = s.run )
t.start()
s.enter( 5,1,event, (2,) ) OUTPUT |
I believe this is a duplicate of bpo-16165, which has already been fixed. |
i saw that issue before i submitted this one, but it says it was fixed a year ago. i assumed a patch from a year ago would be in 3.3.1. when i see an issue closed with a patch accepted, how do i determine which python version will contain that patch? |
Search for the issue number in Misc/NEWS. It looks like it was indeed included in 3.3.1. Can you figure out why that fix didn't fix your problem? |
This is because the scheduler already has executed first event and slept on delaying second event before you have added third event. This is unavoidable for this implementation. sched.scheduler can't be waked when sleep. |
i looks like a different issue. 16165 says you can't add events while the scheduler is running. in my case, i can add them, but they don't run at the correct time. i'll guess at what the problem is... when you start the scheduler, the thread sleeps until the first scheduled event. when you add an event after the scheduler is running, the scheduler doesn't re-evaluate how long it should sleep. sched.enter(), sched.enterabs(), and sched.cancel() should probably send a signal to the scheduler thread to recalculate the time of the next event. |
ok, makes sense. can we put a note in the manual about this limitation? |
I don't think this should be documented as personally I wouldn't expect this use case to be working in the first place. |
Why would you not expect this to work in the first place? I'd think a relatively simple use case for schedulers is using a single thread to do the work of a Timer instead of spawning a thread for every Timer. In that sort of use case, the "timer worker" is constantly pulling tasks and other thread(s) are adding them; for an empty event queue, if thread A adds a task 'a' that delays for 10 minutes and thread B adds a task 'b' that delays for 1 minute, the time at which task 'b' executes changes dramatically based on which thread squeaks out a win on the race to insert into the scheduler queue. As long as task 'a' wins the race, a million other tasks could be scheduled to run before it, but all of them will be stuck behind task 'a' no matter their priority or delay. It should be possible to fix this without too much trouble (and without polling loops), but it would require scheduler to remove the option to customize delayfunc; you'd change the scheduler's RLock to a Condition, have mutations to the event queue notify the Condition, and the run method would replace sleeping outside the locked scope with a wait w/timeout inside it. The only thing blocking a fix for this is backwards compatibility. If people are okay with breaking that, I'll happily contribute a patch, but I want some indication of whether back compat can be sacrificed to make sched actually useful in threaded contexts. |
This absolutely should be documented. If adding an earlier event is not supported then it should raise an exception. Appearing the enqueue the event but not triggering the callback is especially confusing. It may be obvious behavior to someone who has spent time developing this module or working with it but not to someone who just wants to, e.g., build an alarm clock or calendar app. |
Reproduced on 3.11. |
Just for reference I found a working solution: https://github.com/phluentmed/event-scheduler Dealing with events entering before the actual task is ending gets far more complicated than the current sched.scheduler design. The referenced solution uses an additional thread and threading.Condition to handle that case. It is not compatible with the sched.scheduler interface. |
This is not fixable without breaking the sched.scheduler interface. We might add a new scheduler object in the future, but this bug won't be fixed on the existing one. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: