Skip to content

Releases: coleifer/huey

3.0.2

11 Jun 13:34

Choose a tag to compare

  • Redis blocking dequeue no longer swallows ConnectionError -- the error propagates to the worker, which logs it and applies exponential backoff. Previously a downed redis server caused workers to busy-loop silently.
  • Chord callbacks now fire when a member task is revoked, expired or cancelled by a pre-execute hook -- the skipped member contributes a None placeholder result. Previously the callback was silently lost.
  • Scheduler skips missed periodic checks after a stall (e.g. suspend/resume) instead of running them back-to-back, which enqueued duplicate periodic tasks for the current minute.
  • Fix inverted timeout clamp in wait_result() when using notify_result with redis < 6 (or an unknown server version): timeouts over one second were cut to 1s, and sub-second timeouts blocked indefinitely.
  • put_if_empty() is now atomic for the memory and file storage backends, restoring lock_task() mutual exclusion on those backends.
  • FileLock no longer unlinks an existing lock file at construction time, which broke mutual exclusion for any process already holding the lock.
  • Process-worker task timeouts use signal.setitimer(), so float / sub-second timeouts work. Previously a timeout less than 1 second was silently ignored (alarm(0) cancels the timer) and fractional seconds were truncated.
  • Consumer signal handlers only set flags -- logging and greenlet cleanup now happen in the main loop, avoiding re-entrant I/O from signal context.
  • A user-supplied task kwarg named task is no longer dropped during serialization. Context tasks (context=True) inject the task instance into a copy of the kwargs rather than mutating the task's data.
  • MemoryStorage.dequeue() and add_to_schedule() acquire the storage lock, like the other mutating methods.
  • normalize_time() treats delay=0 as "now" rather than ignoring it, so e.g. expires=0 means "expires immediately" instead of "never expires".
  • Redis enqueued_items(limit) returned limit + 1 items from the producer end of the queue; it now returns the next-limit items to be dequeued, matching the other storage backends.
  • Redis-dependent tests are skipped when no local redis server is reachable, instead of failing at import time.

View commits

im-d573b49828

3.0.1

14 May 15:36

Choose a tag to compare

  • Fix bug in redis version parsing when using Elasticache or any other that sends major/minor. redis-py incorrectly parses these as floats because there's only a single decimal, so the version check was breaking.
  • Rename max task option --max-tasks (previously was --max_tasks).

View commits

3.0.0

14 Apr 20:08

Choose a tag to compare

Good things come in THREEs

Three-Witches-oil-Banquo-Macbeth-Henry-Fuseli

  • Add chord() (map -> reduce) and group() (map) primitives.
  • Add timeout (using SIGALRM for process and gevent.Timeout for greenlet) to control task running time. For threads, unfortunately, there's no good mechanism so instead APIs for cooperatively checking timeout are provided on the Task instance.
  • Add simple fixed-window rate_limit() for tasks.
  • Add Result.is_ready() method for checking result readiness.
  • New option for low-latency result fetching, available for RedisHuey. To use, pass notify_result=True when initializing your Huey instance.
  • Add new incr(key, amount=1) to storage API for atomic increment primitive. This is used by chord().
  • Add new wait_result() method to storage APIs for efficiently waiting for a result to become ready. The default implementation uses the exponential backoff from the previous implementation of a blocking Result.get() - so no changes are needed. However if you have a custom storage implementation, this provides a mechanism for pub/sub or other notification of result readiness.
  • Remove Python 2.x compatibility.

View commits

2.6.0

06 Jan 03:11

Choose a tag to compare

We have entered the brave new world of using pyproject.toml and github actions to shovel our shitty open-source software into our users docker containers and venvs and whatever other layers of abstraction I'm too geriatric to have heard about (no I will NOT put my hearing aids in). Welcome to the future, it is looking hellish. I had to beg the assistance of a chatbot trained on other shitty open-source projects to slap this together, nor do I understand what I was copying and pasting. Fellow travelers through the realms of ancient Night and Chaos, take comfort that at least the feeling is an old one.

Me miserable! Which way shall I fly
Infinite wrath and infinite despair?
Which way I fly is hell; myself am hell;
And in the lowest deep a lower deep,
Still threat'ning to devour me, opens wide,
To which the hell I suffer seems a heaven.

Python(r), putting the snake oil in your build system.

im-742836677f

2.5.5

06 Jan 03:03

Choose a tag to compare

  • pypa/pypi is a joke.

View commits

1733152230260308

2.5.4

06 Jan 03:02

Choose a tag to compare

  • Minor bug fixes
  • Fix multiprocessing start method for python 3.14+.

View commits

2.5.3

19 Mar 14:56

Choose a tag to compare

This release adds the oft-requested SIGNAL_ENQUEUED. This signal, of necessity, runs in the calling process, since tasks are enqueued by the application typically. The exception is tasks that are enqueued for retry by the consumer or tasks (including periodic tasks) enqueued by the scheduler. Use care when implementing this signal.

  • Add support for a new SIGNAL_ENQUEUED.
  • Use FOR UPDATE SKIP LOCKED when supported by the database in the sql_huey storage engine.

View commits

im-6e1a4c9e28

2.5.2

25 Sep 18:05

Choose a tag to compare

  • Prevent bad task serialization in schedule from causing a batch of tasks to be lost, see #815..
  • Ensure we catch ResultTimeout which may occur when used with Sentinel, #813.
  • Remove junk SQS implementation I was testing out.

2.5.1

07 Jun 22:02

Choose a tag to compare

  • More makework thanks to the ass-clowns running Python. Fix issue with deprecation of datetime.utcnow() in 3.12.
  • Add API for customizing the TaskWrapper implementation, suitably named get_task_wrapper_class().
  • Make the revoke_all(), restore_all() and is_revoked() more robust for various input types.
  • Fix bug that could occur in the event of a SIGHUP followed by a SIGINT when using thread workers.
  • Added new experimental contrib module for SQS queue and S3 result storage.

Python leadership:

python

2.5.0

22 Sep 15:18

Choose a tag to compare

  • Check to ensure the gevent monkeypatch was applied when running the consumer with greenlet workers, log warning if it is not.
  • Explicitly clear the revoked flag on task instances after execution (#713). This will help reduce junk keys left in the storage if you attempt to revoke a task while it is executing.
  • Add support for delay=, eta= in Huey's .s() and .then() - this adds support for delaying or scheduling pipelines.
  • Add support for rescheduling callback pipelines when rescheduling a task. This is enabled by default (preserve_pipeline=True).
  • Add an on_commit_task() decorator for Django extension that will enqueue the task after any database changes have been committed. This eliminates a common race condition where a task is enqueued and executed before the corresponding database changes have been committed.
  • Allow overriding the delay and eta when raising a RetryTask exception. This provides finer-grained control over when a task should be retried.
  • Add a very simple ResultGroup.as_completed() helper to provide a way to deal with multiple results as they become available. Refs #746.
  • Add an asyncio helper for resolving task results asynchronously. Asyncio users can use await aget_result(result) or await aget_result_group(rg) to fetch a task result in non-blocking fashion.
  • Fix bug in SIGINT and SIGTERM behavior for gevent users.
  • Include lock name when a task fails due to TaskLocked exception (#757).

View commits