def calculate_delay(self, attempt_num: int) -> check.Numeric: backoff = self.backoff jitter = self.jitter base_delay = self.delay or 0 if backoff is Backoff.EXPONENTIAL: calc_delay = ((2**attempt_num) - 1) * base_delay elif backoff is Backoff.LINEAR: calc_delay = base_delay * attempt_num elif backoff is None: calc_delay = base_delay else: check.assert_never(backoff) if jitter is Jitter.FULL: calc_delay = random() * calc_delay elif jitter is Jitter.PLUS_MINUS: calc_delay = calc_delay + ((2 * (random() * base_delay)) - base_delay) elif jitter is None: pass else: check.assert_never(jitter) return calc_delay
def get_execution_time_to_partition_fn( self) -> Callable[[datetime], datetime]: if self.schedule_type is ScheduleType.HOURLY: # Using subtract(minutes=d.minute) here instead of .replace(minute=0) because on # pendulum 1, replace(minute=0) sometimes changes the timezone: # >>> a = create_pendulum_time(2021, 11, 7, 0, 0, tz="US/Central") # # >>> a.add(hours=1) # <Pendulum [2021-11-07T01:00:00-05:00]> # >>> a.add(hours=1).replace(minute=0) # <Pendulum [2021-11-07T01:00:00-06:00]> return lambda d: pendulum.instance(d).subtract(hours=self.offset, minutes=d.minute) elif self.schedule_type is ScheduleType.DAILY: return (lambda d: pendulum.instance(d).replace(hour=0, minute=0). subtract(days=self.offset)) elif self.schedule_type is ScheduleType.WEEKLY: execution_day = cast(int, self.execution_day) day_difference = (execution_day - (self.start.weekday() + 1)) % 7 return (lambda d: pendulum.instance(d).replace(hour=0, minute=0). subtract( weeks=self.offset, days=day_difference, )) elif self.schedule_type is ScheduleType.MONTHLY: execution_day = cast(int, self.execution_day) return (lambda d: pendulum.instance(d).replace(hour=0, minute=0). subtract(months=self.offset, days=execution_day - 1)) else: check.assert_never(self.schedule_type)
def get_cron_schedule( schedule_type: ScheduleType, time_of_day: time = time(0, 0), execution_day: Optional[int] = None, ) -> str: minute = time_of_day.minute hour = time_of_day.hour if schedule_type is ScheduleType.HOURLY: return f"{minute} * * * *" elif schedule_type is ScheduleType.DAILY: return f"{minute} {hour} * * *" elif schedule_type is ScheduleType.WEEKLY: return f"{minute} {hour} * * {execution_day if execution_day != None else 0}" elif schedule_type is ScheduleType.MONTHLY: return f"{minute} {hour} {execution_day if execution_day != None else 1} * *" else: check.assert_never(schedule_type)
def get_cron_schedule( schedule_type: ScheduleType, time_of_day: time = time(0, 0), day_of_week: Optional[int] = 0, ) -> str: minute = time_of_day.minute hour = time_of_day.hour day = day_of_week if schedule_type is ScheduleType.HOURLY: return f"{minute} * * * *" elif schedule_type is ScheduleType.DAILY: return f"{minute} {hour} * * *" elif schedule_type is ScheduleType.WEEKLY: return f"{minute} {hour} * * {day}" elif schedule_type is ScheduleType.MONTHLY: return f"{minute} {hour} {day} * *" else: check.assert_never(schedule_type)
def get_execution_time_to_partition_fn( self) -> Callable[[datetime], datetime]: if self.schedule_type is ScheduleType.HOURLY: return lambda d: pendulum.instance(d).subtract(hours=self.offset, minutes=d.minute) elif self.schedule_type is ScheduleType.DAILY: return lambda d: pendulum.instance(d).subtract( days=self.offset, hours=d.hour, minutes=d.minute) elif self.schedule_type is ScheduleType.WEEKLY: execution_day = cast(int, self.execution_day) day_difference = (execution_day - (self.start.weekday() + 1)) % 7 return lambda d: pendulum.instance(d).subtract(weeks=self.offset, days=day_difference, hours=d.hour, minutes=d.minute) elif self.schedule_type is ScheduleType.MONTHLY: execution_day = cast(int, self.execution_day) return lambda d: pendulum.instance(d).subtract(months=self.offset, days=execution_day - 1, hours=d.hour, minutes=d.minute) else: check.assert_never(self.schedule_type)