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