Add tests for all uncovered BatchEnqueueContext error paths: nil task,
empty/blank typename, invalid options, group rejection, unique rejection,
and broker-down (sleeping broker). Add pipeline error test for rdb.BatchEnqueue
via cancelled context, and TestTaskOptions/TestTaskOptionsNil for the
new Options() accessor on Task.
Add comprehensive doc comments to BatchEnqueueContext, the Broker
interface method, and the RDB implementation explaining that the batch
uses a Redis pipeline (not MULTI/EXEC), so partial success is possible
and individual Lua scripts are atomic but the batch is not.
Fix a bug where Script.Run inside a pipeline only sends EVALSHA without
the automatic EVAL fallback that non-pipeline calls get. On a fresh
Redis (or after SCRIPT FLUSH), this caused NOSCRIPT errors for every
pipeline-batched script invocation. The fix preloads the required Lua
scripts before building the pipeline.
Also roll back the in-memory queuesPublished cache when the pipeline
fails, preventing stale entries from suppressing future SADD calls.
Add TestCancelationPubSubReceiveError to verify that when
Receive() fails in CancelationPubSub(), an error is returned
and the pubsub connection is not leaked.
This provides test coverage for the pubsub.Close() fix that
was missing in the previous commit.
Bahtya
When redis.Subscribe succeeds but Receive() fails, the pubsub
connection was not being closed before returning the error. This caused
the subscriber goroutine to leak a Redis connection on each retry
iteration, eventually exhausting the connection pool.
Fixes#1095
Migrate all CLI command handlers from cobra's Run to RunE, replacing
fmt.Println(err) + os.Exit(1) patterns with idiomatic error returns.
This improves testability and lets cobra handle errors consistently
via the existing SilenceUsage/SilenceErrors configuration.
Also refactor getDuration() and getTime() helpers to return errors
instead of calling os.Exit(1).
Fix a bug in group.go where the error from inspector.Groups() was
never checked, causing silent failures (e.g. on Redis connection
errors) to be misreported as "No groups found".
Previously, parseRedisSentinelURI ignored the /dbnumber path segment,
making it impossible to connect to any DB other than 0 via sentinel URIs.
This adds DB extraction from the URI path, consistent with how
parseRedisURI already handles it for redis:// and rediss:// schemes.
Closes#669
BatchEnqueueContext had a time comparison bug where `now` was captured
before the loop but `processAt` was set to time.Now() inside
composeOptions during each iteration, causing all immediate tasks to be
incorrectly classified as scheduled and rejected.
Fix: move `now` capture inside the loop, after composeOptions.
Additionally, extend BatchEnqueueContext to support scheduled tasks in
the same pipeline. Tasks with a future ProcessAt are now routed to
scheduleCmd (ZADD to scheduled set) instead of being rejected. Only
unique and group tasks remain unsupported.
Changes:
- Add BatchEnqueueItem type pairing TaskMessage with optional ProcessAt
- Update Broker interface, RDB, and testbroker to use BatchEnqueueItem
- Route immediate tasks to enqueueCmd, scheduled tasks to scheduleCmd
- Return correct TaskState (Pending vs Scheduled) in results
- Add tests for immediate, scheduled, and mixed batch scenarios
Adds BatchEnqueue to the Broker interface and RDB implementation that
sends multiple enqueueCmd Lua script invocations in a single Redis
pipeline round-trip. Also adds BatchEnqueueContext to the Client as
the public API, returning per-task results for partial-success handling.
Ref: hibiken/asynq#1069
MEMORY USAGE returns nil for keys that no longer exist (e.g., expired
or deleted task keys). In Lua, nil is converted to false (a boolean).
The script then attempts arithmetic on this boolean value, causing:
ERR user_script:30: attempt to perform arithmetic on local 'bytes'
(a boolean value)
This breaks the /api/queues endpoint in asynqmon, showing "Could not
retrieve queues live data" in the UI.
The fix adds nil guards around all three MEMORY USAGE calls on task
keys, and a divide-by-zero guard on agg_task_sample_size.
Tested in production with Redis 7.2 and asynq v0.25.1 worker.
Fixes#728
Related to #901
* pre-release: v0.26.0
* deps upgrades
* min go version set to 1.24.0
* feat: done add-username-cli (#1083)
* Feature: Add Headers Support to Tasks (#1070)
* feat(task): Add headers support to tasks
* fix: cleanup copy map code
* fix: Add tests
* Add --tls option to dash command (#1073)
* Add --tls option to dash command
* Switch order so it works better when both --tls and --tls_server are set
* docs: update CHANGELOG
---------
Co-authored-by: Artemii Kulikov <91570054+vlle@users.noreply.github.com>
Co-authored-by: Joe <85931983+joejoe-am@users.noreply.github.com>
Co-authored-by: Thomas Hansen <th4019@gmail.com>
* fix: NewScheduler wrongly creates a client whose sharedConnection value is always true
* This is affecting the PeriodicManager as well as the Scheduler
* fix: closing the Client also closes the broker
* The error was also previously unhandled. For shared connections an error will be returned by the broker itself because the sharedConnection bool is also set on the client. This also means we can get rid of the sharedConnection flag on the Scheduler itself and let it work internally.
* Include registration error in the log
* remove chatty debug log
this will show in the logs every 5 seconds as debug (not even trace) which leads to a lot of noise