Danny Vilela
12/21/2021, 11:10 PMIntervalSchedule with pendulum (since that’s what I’ve used for daily/weekly tasks) but he noticed that the results don’t quite line up with what he was expecting:
import pendulum
from prefect.schedules.schedules import IntervalSchedule
from prefect.schedules.clocks import CronClock
# Set our start date.
next_start_date: pendulum.DateTime = (
pendulum.now(tz="America/Los_Angeles")
.start_of(unit="month")
.set(day=2, hour=8, minute=0, second=0)
)
# Set our monthly interval.
monthly: pendulum.Duration = pendulum.duration(months=1)
# Inspect the next few clock emissions.
schedule: IntervalSchedule = IntervalSchedule(start_date=next_start_date, interval=monthly)
print(schedule.next(n=3))
# [
# DateTime(2022, 1, 1, 8, 0, 0, tzinfo=Timezone('America/Los_Angeles')),
# DateTime(2022, 1, 31, 8, 0, 0, tzinfo=Timezone('America/Los_Angeles')),
# DateTime(2022, 3, 2, 8, 0, 0, tzinfo=Timezone('America/Los_Angeles'))
# ]
Why does the IntervalSchedule not fire on 2022-01-02, 2022-02-02, 2022-03-02, etc? It appears to just be incrementing by 30 days, but that’s not quite what I’d expect. Is this a pendulum thing?
(Edit: it’s maybe worth noting that in the example above, just doing next_start_date + monthly does give you the correct DateTime(2022, 1, 2, 8, 0, 0, tzinfo=Timezone('America/Los_Angeles')). So I think it may actually be a Prefect thing?)Danny Vilela
12/22/2021, 12:15 AMpendulum.Duration to the IntervalSchedule function, which “casts” it as a datetime.timedelta before passing to the IntervalClock initializer.
2. In Schedule.next we call _get_clock_events which calls clocks.events.
3. IntervalClock does some book-keeping but ultimately extracts days = interval.days from our input interval. Here, monthly.days defaults to 30 since it has no notion of which month we’re referring to.
Hence, the IntervalClock will always assume that each monthly pendulum.Duration is equivalent to 30 days. I’m not exactly sure how to fix that, but maybe it starts with casting interval to a pendulum.Duration?Anna Geller
import pendulum
from prefect.schedules import CronSchedule
schedule = CronSchedule("0 8 2 * *", start_date=pendulum.today(tz="America/Los_Angeles"))
for sched in schedule.next(20):
print(sched)
but we also support RRule schedules, maybe it can be even easier for youDanny Vilela
12/22/2021, 1:15 AMIntervalScheduler, so I was wondering if it was known. Would it be helpful to file an issue? I couldn’t find any existing issues referring to this situation 🤔
Regardless, thank you @Anna Geller!Zach Schumacher
12/22/2021, 3:55 PM