-
Notifications
You must be signed in to change notification settings - Fork 714
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
AndTrigger does not work with IntervalTrigger #361
Comments
A quick but not elegant fix is changing apscheduler/apscheduler/triggers/combining.py Lines 54 to 56 in ab991eb
to while True:
fire_times = [trigger.get_next_fire_time(None, now)
for trigger in self.triggers] |
Hi @Hanaasagi I also have this issue. For a list of interval triggers, the optimal way to find the next fire time seems to be to compute the least common multiple and just return that. Crons can be reduced to an integer of seconds (akin to
|
Something like this is coming to APScheduler 4.0. |
Closing as duplicate of #281. |
I think this problem is not same as #281
Please test import datetime
from tzlocal import get_localzone
from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.schedulers.blocking import BlockingScheduler
tz = get_localzone()
now = datetime.datetime.now(tz=tz)
def tick():
print('tick')
scheduler = BlockingScheduler()
trigger = AndTrigger([IntervalTrigger(seconds=2, start_date=now),
IntervalTrigger(seconds=3, start_date=now)])
scheduler.add_job(tick, trigger)
scheduler.start() I have specified a same |
The reason is this: Iteration 1: now + 2s, now + 3s This is why they never agree with each other. Maybe it should get a next value for the trigger that produced the earliest fire time and leave the others alone. |
First of all, thank you for such nice library, really love the clean interface and awesome documentation, not to mention that the features are exactly what I was looking for! I have encountered an issue that I think has the same cause as this one. In my case, I have tried combining I think the reason is that Situation is similar with AndTrigger. Do you think this could be the reason, or am I missing something? |
Triggers are stateless and therefore it is not possible to save the previous fire time of each trigger. If you got to issue #281, you see the possibilities being discussed. |
I'm sorry, I don't see the relevance of #281 to this issue? #281 is about comparing the times (when are the two times equal) while this is about combining triggers. Or am I missing something? However, you are right about the problem being in the stateless nature of triggers. For example this trigger doesn't work as expected:
I would expect this trigger to fire on seconds 2, 3, 4, 6, 8, 9, 10,... Instead, it fires on seconds 2, 4, 6, 8, 10,... - because the intervals always start from last fire. In other words, combining interval triggers never works, because the state would need to be saved somewhere (more than just Note that I have solved my issue in the mean time by creating a custom (stateful) trigger and extending an executor, and it works nicely. It is however not a generic solution. |
Combining triggers were never really meant to be used with IntervalTriggers, but rather CronTriggers with which they are quite useful. For interval triggers to work as expected with combining triggers, they would either have to remember their previous calculated fire time (even if that didn't end up as the combined fire time) or start from the start time every time. To fix this I would either have to make triggers stateful or add some kind of native combining mechanism. |
Sure - but as far as I'm concerned, just noting this limitation in documentation would be enough. There are ways around it after all. |
Would there be any chance of getting this reworked on the 3.x version? @agronholm With all due respect - I love this library and all the work you do, thanks! - but I can't couldn't find any roadmap for 4.0 release, other than the 4.0 milestone, which currently is marked as 20% complete and contains open issues from as far as 4 years back. As much as I understand the wish to move ahead and drop legacy code behind, it would be fantastic to have support for the current version too, especially that this functionality is non-trivial. I'm only expressing some doubt regarding having to rely on the 4.0 being released to fix this type of issue without really knowing when that would happen. I found one great statement from some other issue where you state:
which leaves me hope that this bug could be dedicated some attention on this version too. If you could provide some context on when we could be looking to expect 4.0 that would be great too! Once again, massive thanks for all the work and hope these observations find you well :) |
I've already fixed this design issue in master, but understand that I am basically working on it alone on my free time, with at least 5 other F/OSS projects consuming my time as well. Fixing this issue properly meant making a major design change – namely adding "thresholds" and making triggers stateful. This is not a change that can be backported to the 3.x series. With that in mind, what exactly do you expect me to do about this in the 3.x series? I can publish some sort of fix if I can be reasonably convinced that it doesn't break anything else. |
Truly, more than anything I hoped for some information on when we could expect the 4.0. Like I said, I understand the difficultly of providing the long term support and fighting design legacy. Please don't think I wanted to raise these points as an expectation claim; I merely wanted to get more information on when we could see this functionality working - either through a fix on 3.x or a 4.0 release. Apologies if that came across inappropriately. You say that you already fixed this design issue on master - does master contain a stable version of APS that you encourage us to use? Lastly, once again thank you for working on this project, even more so if that's only done in your free time and with other projects in parallel. Your work is appreciated. |
You didn't – you were far more courteous than most people asking about this 😄 Here is the mid-term plan: I will first focus on my AnyIO project (getting v2.0 out the door). APScheduler 4.0 will depend on the features there to provide proper support for both async and sync schedulers. This process is fairly far along so I expect this part to be completed some time this month. Once that's done, I will resume work on shared job store support and updating the scheduler API. That's the hardest part, and once it's been dealt with, it should be fairly smooth sailing from there on. Barring no further major delays, I expect a beta release within the next three months. How's that for a roadmap?
No, apart from the trigger subsystem, the master branch is currently a mess due to some parts of the design having been updated and some parts not.
Thank you 😃 |
That's fantastic, thank you for the update! Thanks for clarifying how your roadmap looks like. It may be useful for other users to see this information available more publicly too. May I propose a naive suggestion? It seems like 4.0 contains quite a lot of things under its hood. Naturally, without understanding the source code this is just me hypothesising, but would you consider breaking up the releases into smaller stages? Would maybe the AnyIO integration , the trigger overhaul, and the shared job store support be doable as separate updates, eg. 4.0, 4.1, 4.2? I'm only suggesting this as it may help you streamline the releasing process if these indeed could be separated. Best of luck with the AnyIO too, looks super cool! |
I'm trying to cram as many of the planned backwards incompatible changes into v4.0 as I possibly can. It may be years before I get around to making such a huge push again. Shared job stores is a core new feature in v4.0 so that has to go in. Enhanced async support is too. The trigger overhaul and broader serialization support is pretty much done already. What changes do you then propose I would leave to minor releases? |
In my opinion - again very naively - I'd suggest to make each of these things you list a separate version update.
Yeah, I understand if you want to go this way. I only wanted to suggest that having smaller independent releases would be easier and more reliable than one big all-breaking change. Both for you - as less work would be needed for each iteration and it would be easier to ensure that code is bug-free - and for the users - as the updates would be more frequent and easier to adapt to. That's just one point of view though, and I totally understand there may be good reasons for not doing it the way I suggest, especially if these changes you list rely on each other. Furthermore, if most of work is already done and tested, then my suggestions are even less relevant; maybe only as something to keep in mind in the future. If there are some of these features you listed that you still haven't started working on - shared job stores, enhanced async support, or other - then my suggestion would be to see if they could become v4.1, v4.2, etc. or even v5.0. Again - only a suggestion. |
Making these changes incrementally, without changing the API, would be impossible since they alter the semantics so radically. |
Update: work on AnyIO v2.0 is virtually complete. There are a couple blocker issues I need to take care of before moving on with the release. |
Thanks for the update and congrats @agronholm! Looking forward to it big time 👌👌 |
AnyIO v2.0.0b1 has been released. I will try out the new features first with my smtpproto side project. My main interest is using the new |
I've released smtpproto and the results of using |
I've posted issue #465 to track v4.0 development so I will stop posting updates here. |
I've created #906 to track a better solution to this problem. |
Recently, I learn how to use apscheduler, and I find something interesting. From the latest doc's example,
AndTrigger
can be used as:Actually, it doesn't work. I have read #281 and #309, and know that the time generated by the two triggers never coincide.
So, if I sepcify a
start_date
likeIt works as expected.
But when schedule a job, it does work.
The real problem it that
AndTrigger
may not supportIntervalTrigger
In
_process_jobs
, it will calculate run times .apscheduler/apscheduler/schedulers/base.py
Lines 970 to 972 in ab991eb
apscheduler/apscheduler/job.py
Lines 123 to 137 in ab991eb
apscheduler/apscheduler/triggers/combining.py
Lines 53 to 62 in ab991eb
apscheduler/apscheduler/triggers/interval.py
Lines 52 to 66 in ab991eb
In the loop of calculating
next_run_time
inAndTrigger
, we only change the value ofnow
. But inIntervalTrigger
, if we passprevious_fire_time
which is notNone
, it will just add the interval. So it caused a dead loop.Similarly, When we combine
IntervalTrigger
andCronTrigger
, ifprevious_fire_time
is notNone
, onlyCronTrigger
will walk.The text was updated successfully, but these errors were encountered: