Skip to content

Daylight saving to winter time caused scheduler to stop #636

@kimdre

Description

@kimdre

Tonight my scheduler app stopped running right after the time was set back by one hour.
Did anyone experience something similiar?
Unfortunately there were no errors/exceptions in the logs, this is the only information I can provide:

[2024-10-27 02:59:12.406] [client.py.start_scheduler:83] INFO: Running pending jobs: ['check_100th_checkins']
[2024-10-27 02:01:40.857] [main.py.<module>:28] INFO: Stopping App...
[2024-10-27 02:01:40.861] [main.py.<module>:33] INFO: App stopped.

My main:

if __name__ == '__main__':
    log.info("Starting App...")

    loop = asyncio.new_event_loop()

    mq_connection = loop.run_until_complete(get_connection(loop))
    message_publisher = MessagePublisher(mq_connection)

    try:
        loop.run_until_complete(message_publisher.connect())
        loop.run_until_complete(start_scheduler(loop=loop, message_publisher=message_publisher))

    except (KeyboardInterrupt, SystemExit):
        pass

    except Exception as e:
        log.error(e, exc_info=True)

    finally:
        log.info("Stopping App...")
        loop.run_until_complete(message_publisher.disconnect())
        loop.run_until_complete(mq_connection.close())
        loop.stop()
        loop.close()
        log.info("App stopped.")

My scheduler:

def run_async(func, loop: asyncio.AbstractEventLoop, *args):
    """
    Wrapper to run async functions in the scheduler

    :param func: The async function to run
    :param loop: The event loop
    :param args: The arguments to pass to the function
    """

    logger.debug(f"Running async function: {func}")
    loop.call_soon_threadsafe(loop.create_task, func(*args))


async def start_scheduler(loop: asyncio.AbstractEventLoop, message_publisher: MessagePublisher):
    """
    Start the scheduler

    :param message_publisher: The message publisher
    :param loop: The event loop
    """

    logger.info("Starting scheduler...")

    # Health check job

    schedule.every(5).seconds.do(run_async, write_health, loop)
    schedule.run_all()

    # Schedule normal jobs

    schedule.every(15).minutes.do(run_async, check_100th_checkins, loop, message_publisher)

    schedule.every().day.at("10:00").do(run_async, check_birthdays, loop, message_publisher)
    schedule.every().day.at("10:15").do(run_async, check_inactive_midterm_members_premium, loop, message_publisher)
    schedule.every().day.at("10:30").do(run_async, check_inactive_longterm_members_premium, loop, message_publisher)
    schedule.every().day.at("10:45").do(run_async, check_active_members_weekend_only_premium, loop, message_publisher)
    schedule.every().day.at("12:45").do(run_async, check_inactive_new_members_premium, loop, message_publisher)
    schedule.every().day.at("13:00").do(run_async, check_inactive_members, loop, message_publisher)

    logger.info("Scheduler started.")

    # Create multiline string with scheduled job names, interval and next run time
    jobs = "\n• ".join(
        [
            f"{job.job_func.args[0].__name__} - runs at {job.at_time or f'every {job.interval} {job.unit}'} - next run: {job.next_run}"
            for job in schedule.jobs
        ]
    )
    logger.info(f"Scheduled jobs:\n{jobs}")

    while True:
        try:
            pending_jobs = get_pending_jobs(schedule.jobs)
            if pending_jobs:
                jobs = [job.job_func.args[0].__name__ for job in pending_jobs]
                logger.info(f"Running pending jobs: {jobs}")
            schedule.run_pending()
            await asyncio.sleep(1)
        except asyncio.CancelledError:
            break

    logger.info("Scheduler stopped.")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions