Skip to content

Releases: tokibito/django-database-task

v0.6.0

Choose a tag to compare

@tokibito tokibito released this 30 Sep 16:08
de641e5

A task no longer runs twice when several workers share a queue, a task whose code cannot be imported fails visibly instead of hanging in RUNNING, and the queue can be monitored from code and from /tasks/status/. Windows Server is now a supported place to run the worker.

Existing projects need no changes, with one exception: TaskBroker.enqueue(), deprecated in 0.5, is now gone — see Removed below.

Added

  • Windows Server. GracefulShutdown handles SIGBREAK, so a worker stopped with Ctrl-Break or by a service manager finishes the running task before exiting. The README gained NSSM and WinSW service examples and a Task Scheduler shape for running from a job scheduler.
  • A monitoring API. get_queue_stats() returns the counts per status, the number of delayed tasks not yet due, and how long the oldest and newest pending task has been waiting; get_task_counts() returns the counts alone. The keys are those of django-tasks-redis, so one collector reads both.
  • Purging one task's results. purge_completed_database_tasks --task-path and task_path on /tasks/purge/ delete only the results of that task, such as a heartbeat enqueued every minute.
  • Purging from your own code. purge_completed_tasks() does what the command does, for a project that purges from a periodic task. Its defaults follow django-tasks-redis: the default backend only, keeping the last 7 days. The command and the endpoint keep their defaults.
  • Simplified Chinese, Brazilian Portuguese and Spanish translations of the admin and the management command help.
  • Task path and priority filters in the admin task list.

Changed

  • GET /tasks/status/ returns the queue stats alongside pending_count, which is unchanged, as is the endpoint's authentication.

Removed

  • TaskBroker.enqueue(), deprecated in 0.5 and removed here as announced. A broker that overrides it instead of notify() is no longer called, and every task logs Broker X failed to notify about task Y at ERROR; the task stays in the database, so the worker and the HTTP endpoints still run it. Rename the method to notify(). Bundled brokers and the BROKER option are unaffected.

Fixed

  • A task could run twice when more than one worker polled the same queue. run_task() now claims the task in a locked transaction and returns None for a task another worker claimed first.
  • A task whose function could not be imported was left RUNNING with no error recorded. It is now FAILED with the traceback, so the admin shows it and Retry failed tasks runs it again once the code is fixed.
  • An invalid --empty-exit-code or --failed-exit-code printed a traceback and exited 1; it is now a usage error with exit code 2.
  • Two broker-path log records now carry the fields the README documents.
  • The admin column headers and the management command help are now translated.

See CHANGELOG.md for the full entry, including the test suite changes for Windows.

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@tokibito tokibito released this 05 Sep 08:00
82fc8c4

Workers recover from being killed, PostgreSQL gets a broker that needs no extra service, and the worker reports what happened in a form a job scheduler and a log aggregator can read.

Existing projects need no changes, with one exception: get_auth_handler() (singular), deprecated in 0.4, is now gone — see Removed below.

Added

  • Recovery of tasks left in RUNNING (manage.py requeue_stale_database_tasks --older-than 15m). A worker killed outright — SIGKILL, the OOM killer, a node failure — never writes a result, so the task it held stays RUNNING and no other worker picks it up. The new command puts those tasks back in READY. --older-than is required and has to be longer than the longest task takes to run; --max-attempts (default 3) marks a task FAILED rather than requeueing one that kills its own worker forever, and --mark-failed is there for tasks that are not safe to run twice. Also available as django_database_task.requeue_stale_tasks() and as a Django admin action.
  • PostgreSQL LISTEN/NOTIFY broker (django_database_task.postgres.PostgresNotifyDatabaseBackend, pip install django-database-task[postgres]). Notifies a channel of the database the tasks are already stored in, so a waiting worker starts the task in milliseconds instead of on the next poll. No queue, no credentials, no extra service. The notification is sent with pg_notify() inside the transaction that inserted the task, so a worker is never told about a task it cannot yet see or one whose transaction was rolled back.
  • Exit codes for job schedulers: run_database_tasks --empty-exit-code and --failed-exit-code. Both default to 0, so nothing changes for an existing cron line or Kubernetes Job until they are set.
  • Structured log fields. Log records now carry task_id, task_path, queue_name, priority, backend_alias, worker_id, plus status, duration_ms and error_class where they apply, instead of only interpolating them into the message. Task started, Worker started and Worker finished records are new.

Changed

  • A broker's enqueue() method is now called notify(). The old name read as if it enqueued the task, which is the backend's job: a broker is only told about a task the database already holds.

Deprecated

  • TaskBroker.enqueue(). A broker that overrides it is still called, with a DeprecationWarning, and stops being called in 0.6. Rename it to notify(). Bundled brokers and the BROKER option are unaffected.

Removed

  • get_auth_handler() (singular), deprecated in 0.4 and removed here as announced. A backend that overrides it is no longer called, and unless it also overrides get_auth_handlers() or sets AUTH_HANDLERS its endpoints are left unauthenticated. Override get_auth_handlers() instead. The AUTH_HANDLERS and CLOUD_TASKS_* options and the bundled backends are unaffected.

See CHANGELOG.md for the full entry, including the documentation added in this release.

Full Changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@tokibito tokibito released this 23 Aug 18:00
59e70ee

Brokers — the services that trigger execution of a saved task — are now separate from the task backend, and Amazon SQS joins Cloud Tasks as one of them.

Existing projects need no changes. The settings, the URLs, the management commands and their defaults all behave as they did in 0.3.

Added

  • Amazon SQS broker (django_database_task.sqs.SQSDatabaseBackend, pip install django-database-task[sqs]). Sends a message naming the task, and run_database_tasks receives it. A task deferred beyond the 15 minute SQS delay limit stays in the database for the worker's database sweep.
  • --source for run_database_tasks: auto (default), db, broker or both. auto means both when the backend has a broker a worker can receive from, and db otherwise, so the command is run the same way as before either way. --wait-time and --max-messages go with it.
  • The broker abstraction (django_database_task.brokers): TaskBroker, HTTPPushBroker and PullBroker. A project attaches its own with the BROKER option.
  • Several authentication handlers per backend, through get_auth_handlers(). A request is accepted as soon as one handler accepts it, so the service that calls the endpoints and an external cron job can use different credentials.
  • Bundled authentication handlers in django_database_task.auth: SharedSecretAuth, HMACAuth and StaffOnlyAuth, with build_signature() for callers that have to sign a request.

Fixed

  • Enabling Cloud Tasks OIDC no longer locks every other caller out of the task endpoints. Since 0.3.1 the OIDC handler was applied to all of them, so an external cron job calling /tasks/run/ or /tasks/purge/ was rejected.
  • The Cloud Tasks tests were skipped on every run, in CI included, because the cloudtasks extra was never installed.

Deprecated

  • get_auth_handler() (singular). It still works, with a DeprecationWarning, and is removed in 0.5. Override get_auth_handlers() instead.

See CHANGELOG.md for the full entry, including the documentation added in this release.

Full Changelog: v0.3.1...v0.4.0

v0.3.1

Choose a tag to compare

@tokibito tokibito released this 22 Aug 17:21

Full Changelog: v0.3.0...v0.3.1

v0.3.0

Choose a tag to compare

@tokibito tokibito released this 22 Aug 16:58