Releases: coleifer/huey
3.0.2
- 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
Noneplaceholder 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 usingnotify_resultwith 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, restoringlock_task()mutual exclusion on those backends.FileLockno 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
taskis 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()andadd_to_schedule()acquire the storage lock, like the other mutating methods.normalize_time()treatsdelay=0as "now" rather than ignoring it, so e.g.expires=0means "expires immediately" instead of "never expires".- Redis
enqueued_items(limit)returnedlimit + 1items from the producer end of the queue; it now returns the next-limititems 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.
3.0.1
- 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).
3.0.0
Good things come in THREEs
- Add
chord()(map -> reduce) andgroup()(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=Truewhen initializing your Huey instance. - Add new
incr(key, amount=1)to storage API for atomic increment primitive. This is used bychord(). - 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 blockingResult.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.
2.6.0
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.
2.5.5
2.5.4
- Minor bug fixes
- Fix multiprocessing start method for python 3.14+.
2.5.3
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 LOCKEDwhen supported by the database in thesql_hueystorage engine.
2.5.2
2.5.1
- More makework thanks to the ass-clowns running Python. Fix issue with deprecation of
datetime.utcnow()in 3.12. - Add API for customizing the
TaskWrapperimplementation, suitably namedget_task_wrapper_class(). - Make the
revoke_all(),restore_all()andis_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:
2.5.0
- 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
delayandetawhen raising aRetryTaskexception. 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
asynciohelper for resolving task results asynchronously. Asyncio users can useawait aget_result(result)orawait 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
TaskLockedexception (#757).