Skip to content

Releases: agronholm/apscheduler

3.11.2

22 Dec 00:39

Choose a tag to compare

  • Fixed an issue where a job using a CronTrigger scheduled in a repeated time interval during DST transitions could cause the scheduler to get stuck in an infinite loop (#1021; PR by @SoulofAkuma)

3.11.1

31 Oct 18:55

Choose a tag to compare

  • Fixed scheduler.shutdown() not raising SchedulerNotRunning (or raising the wrong exception) for asynchronous schedulers when the scheduler is in fact not running
  • Fixed CronTrigger sticking on a folded datetime during the fall-back DST transition (#1021 <#1021>_; PR by @berianjames)`

4.0.0a6

27 Apr 08:36

Choose a tag to compare

  • BREAKING Refactored AsyncpgEventBroker to directly accept a connection string, thus eliminating the need for the AsyncpgEventBroker.from_dsn() class method
  • BREAKING Added the extend_acquired_schedule_leases() data store method to prevent other schedulers from acquiring schedules already being processed by a scheduler, if that's taking unexpectedly long for some reason
  • BREAKING Added the extend_acquired_job_leases() data store method to prevent jobs from being cleaned up as if they had been abandoned (#864)
  • BREAKING Changed the cleanup() data store method to also be responsible for releasing jobs whose leases have expired (so the schedulers responsible for them have probably died)
  • BREAKING Changed most attributes in Task and Schedule classes to be read-only
  • BREAKING Refactored the release_schedules() data store method to take a sequence of ScheduleResult instances instead of a sequence of schedules, to enable the memory data store to handle schedule updates more efficiently
  • BREAKING Replaced the data store lock_expiration_delay parameter with a new scheduler-level parameter, lease_duration which is then used to call the various data store methods
  • BREAKING Added the job_result_expiration_time field to the Schedule class, to allow the job results from scheduled jobs to stay around for some time (#927)
  • BREAKING Added an index for the created_at job field, so acquiring jobs would be faster when there are a lot of them
  • BREAKING Removed the job_executor and max_running_jobs parameters from add_schedule() and add_run_job() (explicitly configure the task using configure_task() or by using the new @task decorator
  • BREAKING Replaced the default_job_executor scheduler parameter with a more comprehensive task_defaults parameter
  • Added the @task decorator for specifying task configuration parameters bound to a function
  • BREAKING Changed tasks to only function as job templates as well as buckets to limit maximum concurrent job execution
  • BREAKING Changed the timezone argument to CronTrigger.from_crontab() into a keyword-only argument
  • BREAKING Added the metadata field to tasks, schedules and jobs
  • BREAKING Added logic to store last_fire_time in datastore implementations (PR by @hlobit)
  • BREAKING Added the reap_abandoned_jobs() abstract method to DataStore which the scheduler calls before processing any jobs in order to immediately mark jobs left in an acquired state when the scheduler crashed
  • Added the start_time and end_time arguments to CronTrigger.from_crontab() (#676)
  • Added the psycopg event broker
  • Added useful indexes and removed useless ones in SQLAlchemyDatastore and MongoDBDataStore
  • Changed the lock_expiration_delay parameter of built-in data stores to accept a timedelta as well as int or float
  • Fixed serialization error with CronTrigger when pausing a schedule (#864)
  • Fixed TypeError: object NoneType can't be used in 'await' expression at teardown of SQLAlchemyDataStore when it was passed a URL that implicitly created a synchronous engine
  • Fixed serializers raising their own exceptions instead of SerializationError and DeserializationError as appropriate
  • Fixed repr() outputs of schedulers, data stores and event brokers to be much more useful and reasonable
  • Fixed race condition in MongoDBDataStore that allowed multiple schedulers to acquire the same schedules at once
  • Changed SQLAlchemyDataStore to automatically create the explicitly specified schema if it's missing (PR by @zhu0629)
  • Fixed an issue with CronTrigger infinitely looping to get next date when DST ends (#980; PR by @hlobit)
  • Skip dispatching extend_acquired_job_leases with no jobs (PR by @JacobHayes)
  • Fixed schedulers not immediately processing schedules that the scheduler left in an acquired state after a crash
  • Fixed the job lease extension task exiting prematurely while the scheduler is starting (PR by @JacobHayes)
  • Migrated test and documentation dependencies from extras to dependency groups
  • Fixed add_job() overwriting task configuration (PR by @mattewid)

3.11.0

24 Nov 19:42

Choose a tag to compare

  • Dropped support for Python 3.6 and 3.7
  • Added support for ZoneInfo time zones and deprecated support for pytz time zones
  • Added CalendarIntervalTrigger, backported from the 4.x series
  • Added the ability to export and import jobs via scheduler.export_jobs() and scheduler.import_jobs(), respectively
  • Removed the dependency on six
  • Changed ProcessPoolExecutor to spawn new subprocesses from scratch instead of forking on all platform
  • Fixed AsyncIOScheduler inadvertently creating a defunct event loop at start, leading to the scheduler not working at all
  • Fixed ProcessPoolExecutor not respecting the passed keyword arguments when a broken pool was being replaced

4.0.0a5

15 May 23:15

Choose a tag to compare

  • BREAKING Added the cleanup() scheduler method and a configuration option (cleanup_interval). A corresponding abstract method was added to the DataStore class. This method purges expired job results and schedules that have exhausted their triggers and have no more associated jobs running. Previously, schedules were automatically deleted instantly once their triggers could no longer produce any fire times.
  • BREAKING Made publishing JobReleased events the responsibility of the DataStore implementation, rather than the scheduler, for consistency with the acquire_jobs() method
  • BREAKING The started_at field was moved from Job to JobResult
  • BREAKING Removed the from_url() class methods of SQLAlchemyDataStore, MongoDBDataStore and RedisEventBroker in favor of the ability to pass a connection url to the initializer
  • Added the ability to pause and unpause schedules (PR by @WillDaSilva)
  • Added the scheduled_start field to the JobAcquired event
  • Added the scheduled_start and started_at fields to the JobReleased event
  • Fixed large parts of MongoDBDataStore still calling blocking functions in the event loop thread
  • Fixed JSON serialization of triggers that had been used at least once
  • Fixed dialect name checks in the SQLAlchemy job store
  • Fixed JSON and CBOR serializers unable to serialize enums
  • Fixed infinite loop in CalendarIntervalTrigger with UTC timezone (PR by unights)
  • Fixed scheduler not resuming job processing when max_concurrent_jobs had been reached and then a job was completed, thus making job processing possible again (PR by MohammadAmin Vahedinia)
  • Fixed the shutdown procedure of the Redis event broker
  • Fixed SQLAlchemyDataStore not respecting custom schema name when creating enums
  • Fixed skipped intervals with overlapping schedules in AndTrigger (#911 <#911>_; PR by Bennett Meares)
  • Fixed implicitly created client instances in data stores and event brokers not being closed along with the store/broker

4.0.0a4

13 Nov 00:52

Choose a tag to compare

  • BREAKING Renamed any leftover fields named executor to job_executor (this breaks data store compatibility)
  • BREAKING Switched to using the timezone aware timestamp column type on Oracle
  • BREAKING Fixed precision issue with interval columns on MySQL
  • BREAKING Fixed datetime comparison issues on SQLite and MySQL
  • BREAKING Worked around datetime microsecond precision issue on MongoDB
  • BREAKING Renamed the worker_id field to scheduler_id in the JobAcquired and JobReleased events
  • BREAKING Added the task_id attribute to the ScheduleAdded, ScheduleUpdated and ScheduleRemoved events
  • BREAKING Added the finished attribute to the ScheduleRemoved event
  • BREAKING Added the logger parameter to Datastore.start() and EventBroker.start() to make both use the scheduler's assigned logger
  • BREAKING Made the apscheduler.marshalling module private
  • Added the configure_task() and get_tasks() scheduler methods
  • Fixed out of order delivery of events delivered using worker threads
  • Fixed schedule processing not setting job start deadlines correctly

4.0.0a3

01 Oct 21:30

Choose a tag to compare

  • BREAKING The scheduler classes were moved to be importable (only) directly from the apscheduler package (apscheduler.Scheduler and apscheduler.AsyncScheduler)
  • BREAKING Removed the "tags" field in schedules and jobs (this will be added back when the feature has been fully thought through)
  • BREAKING Removed the JobInfo class in favor of just using the Job class (which is now immutable)
  • BREAKING Workers were merged into schedulers. As the Worker and AsyncWorker classes have been removed, you now need to pass role=SchedulerRole.scheduler to the scheduler to prevent it from processing due jobs. The worker event classes (WorkerEvent, WorkerStarted, WorkerStopped) have also been removed.
  • BREAKING The synchronous interfaces for event brokers and data stores have been removed. Synchronous libraries can still be used to implement these services through the use of anyio.to_thread.run_sync().
  • BREAKING The current_worker context variable has been removed
  • BREAKING The current_scheduler context variable is now specified to only contain the currently running instance of a synchronous scheduler (apscheduler.Scheduler). The asynchronous scheduler instance can be fetched from the new current_async_scheduler context variable, and will always be available when a scheduler is running in the current context, while current_scheduler is only available when the synchronous wrapper is being run.
  • BREAKING Changed the initialization of data stores and event brokers to use a single start() method that accepts an AsyncExitStack (and, depending on the interface, other arguments too)
  • BREAKING Added a concept of "job executors". This determines how the task function is executed once picked up by a worker. Several data structures and scheduler methods have a new field/parameter for this, job_executor. This addition requires database schema changes too.
  • Dropped support for Python 3.7
  • Added support for Python 3.12
  • Added the ability to run jobs in worker processes, courtesy of the processpool executor
  • Added the ability to run jobs in the Qt event loop via the qt executor
  • Added the get_jobs() scheduler method
  • The synchronous scheduler now runs an asyncio event loop in a thread, acting as a faΓ§ade for AsyncScheduler
  • Fixed the schema parameter in SQLAlchemyDataStore not being applied
  • Fixed SQLalchemy 2.0 compatibility