zoolutions/sidekiq-unique-jobs
62.0
Adequate · 19 September 2026
12.1k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
This system is a Ruby gem that enforces job uniqueness for Sidekiq background workers by managing distributed locks in Redis. It provides a modular locking architecture with multiple strategies to prevent duplicate execution, alongside configurable conflict resolution policies such as rejecting, replacing, or rescheduling colliding jobs. The library includes tooling for monitoring active locks, recovering orphaned jobs, and validating configurations, ensuring robust and performant job scheduling.
How it got here
2012–2015 — Architectural modernization and reliability
12 changes.
The project underwent a major architectural refactor to replace legacy middleware with a modular locking strategy hierarchy and modern dependencies like concurrent-ruby. This period introduced robust features such as a CLI, batch deletion, and crash-recovery fetch mechanisms, while upgrading the stack to Rails 8.1 and Sidekiq 8. Comprehensive test infrastructure and development tooling were established to support these changes and ensure code quality.
2018–2019 — Locking architecture and UI overhaul
25 changes.
The project significantly refactored its core locking mechanism by introducing explicit on-conflict strategies, rewriting Lua scripts for performance, and establishing a dedicated Redis abstraction layer. This period also saw the addition of a comprehensive Web UI for managing locks and a substantial expansion of the test suite to cover the new middleware and conflict resolution logic.
2021–2026 — Sidekiq 8 compatibility and test coverage
4 changes.
The project focused on ensuring compatibility with Sidekiq versions 8.0 and 8.1 by adding Appraisal gemfiles for explicit version testing. Significant effort was directed toward expanding test coverage, including integration tests for lock behavior under high latency and comprehensive unit tests for job fetch, lock validation, and orphan recovery logic.
Features
Add RSpec matcher for validating Sidekiq worker configuration
Users can now use the new \have\_valid\_sidekiq\_options\ RSpec matcher to verify that their Sidekiq workers have correct unique/lock configurations. This matcher automatically validates the worker's Sidekiq options against the library's validation rules and provides clear failure messages if the configuration is invalid, simplifying testing of job locking setups.
_lib/sidekiq\_unique\jobs/rspec · high confidence
Added changelog generation task
A new Rake task has been added to lib/tasks/changelog.rake that automates the generation of the project's changelog. When executed, the task switches to the main branch, runs the github\_changelog\_generator tool using the configured GitHub user and project details, and automatically commits the resulting changes.
lib/tasks · high confidence
Added development and benchmarking tooling scripts
The repository now includes a suite of executable scripts in the \bin/\ directory to support development, performance testing, and maintenance. This includes \bin/benchmark\ and \bin/benchmark\_improvements\ for measuring lock/unlock throughput, contention, and memory usage, as well as \bin/compare\_performance\ and \bin/memory\_compare\ for cross-branch and specific optimization comparisons. Additional tools like \bin/profiling\ (using RubyProf) and \bin/memory\_profile\ are provided for deep-dive analysis, while standard Bundler-generated binstubs for \bundle\, \rake\, \rspec\, and \rubocop\ are now committed to the repository.
bin · high confidence
Application scaffolding with Tailwind CSS, DaisyUI, and Bun runtime
The myapp directory has been initialized with a new frontend styling stack using Tailwind CSS and the DaisyUI component library, configured with multiple themes (light, dark, cyberpunk, dracula) and typography/forms plugins. The project now uses Bun (version 1.3.11) as the JavaScript runtime, specified in .bun-version and .tool-versions, and runs on Ruby 4.0.2. Environment configuration is standardized via .env and .env.test files defining database, Redis, and Rails thread pool settings. A comprehensive set of Heroicons micro SVGs has been added to the assets, and the Procfile.dev is configured to start the Rails server, CSS watcher, and ten Sidekiq worker processes.
myapp · high confidence
Initial project scaffolding and configuration
The repository has been initialized with a comprehensive set of configuration files to standardize development workflows and code quality. This includes \.editorconfig\ for consistent indentation and whitespace, \.rubocop.yml\ with performance and RSpec plugins targeting Ruby 3.2, and \.fasterer.yml\ for Ruby speed optimizations. Documentation linting is enforced via \.markdownlintrc\ and \.mdlrc\. Testing infrastructure is established with \.rspec\ for RSpec defaults and \.simplecov\ for branch coverage reporting (90% line, 80% branch thresholds). The project also introduces \Appraisals\ to test against Sidekiq 8.0 and 8.1, and \AGENTS.md\ to provide unified instructions for AI coding assistants. Documentation is generated via \.yardopts\, and release security is defined in \RELEASING.md\ using trusted publishing and Sigstore.
(repo-wide) · high confidence
Introduces new CLI, batch deletion, and reliable fetch mechanisms
The gem now includes a command-line interface (lib/sidekiq\_unique\_jobs/cli.rb) allowing operators to list and delete unique digests by pattern, with a dry-run mode for safety. A new batch deletion system (lib/sidekiq\_unique\_jobs/batch\_delete.rb) optimizes the removal of multiple digests by processing them in chunks of 500 via pipelined Redis commands, reducing overhead compared to individual deletions. Additionally, a reliable fetch strategy (lib/sidekiq\_unique\_jobs/fetch/reliable.rb) is introduced, using atomic LMOVE operations and per-process heartbeats to ensure jobs are not lost during crashes and to provide crash recovery for in-progress jobs.
_lib/sidekiq\_unique\jobs · high confidence
New Locks management interface in the Sidekiq Web UI
The Sidekiq Web UI now includes a dedicated 'Locks' section that allows users to view, filter, and manage unique job locks. This new interface displays lock metrics (acquired, denied, released, failures) over the last hour, lists active locks with details such as worker, queue, type, and TTL, and provides options to delete individual locks or all locks at once. Pagination is supported for large lists, and a detailed view for each lock shows locked job IDs and allows unlocking specific jobs.
_lib/sidekiq\_unique\jobs/web/views · high confidence
Removals
Removal of legacy unique jobs server middleware
The legacy \SidekiqUniqueJobs::Middleware::Server::UniqueJobs\ middleware has been removed. This component previously handled job uniqueness by deleting a Redis key (hashed from the job arguments) after job execution, a mechanism that is no longer part of the library's current architecture.
_lib/sidekiq\_unique\jobs/middleware/server · high confidence
Behavioural changes
Introduce dedicated client and server middleware classes for job locking
The library now uses explicit \SidekiqUniqueJobs::Middleware::Client\ and \SidekiqUniqueJobs::Middleware::Server\ classes to handle job uniqueness. The client middleware intercepts jobs before they are pushed to Sidekiq, acquiring a lock and yielding execution only if the lock is successfully obtained. The server middleware processes jobs on the worker side, delegating execution to the lock instance. This separation ensures that uniqueness checks are applied consistently at both the push and processing stages.
_lib/sidekiq\_unique\jobs/middleware · high confidence
Major architectural refactor and dependency update
The library has been significantly refactored to support a more modular and robust architecture. The main entry point now loads a comprehensive set of components, including new lock strategies (until\_executed, until\_executing, until\_expired, while\_executing, while\_executing\_reject, until\_and\_while\_executing), a new lock configuration system, and a reliable fetch mechanism. The old client middleware implementation has been removed, indicating a shift in how uniqueness is enforced. Additionally, the gem now explicitly depends on the \concurrent-ruby\ and \redis-client\ libraries, moving away from older or implicit dependencies.
lib · high confidence
New Redis entity abstraction layer for data types
The library introduces a new \SidekiqUniqueJobs::Redis\ module containing an \Entity\ base class and specific wrappers for Redis data structures (String, Hash, List, Set, SortedSet). This refactors how the library interacts with Redis, providing a consistent object-oriented interface for operations like existence checks, counting, and retrieving entries, while also handling driver compatibility differences such as preferring \exists?\ over \exists\ where available.
_lib/sidekiq\_unique\jobs/redis · high confidence
New on-conflict strategies for handling unique job collisions
The library now provides explicit strategies for handling job conflicts, allowing users to define specific behaviors when a unique job lock is detected. New classes include \Log\ to simply record the conflict, \Raise\ to trigger a retry by throwing an error, \Reject\ to move conflicting jobs to the dead queue (with compatibility for different Sidekiq versions), \Replace\ to delete the existing job and lock before re-queuing, and \Reschedule\ to delay and re-execute the job while preventing infinite recursion. These strategies replace the previous implicit or less granular conflict handling mechanisms.
_lib/sidekiq\_unique\_jobs/on\conflict · high confidence
Redesigned Lua scripts for Sidekiq Unique Jobs with optimized lock lifecycle and recovery
The Lua scripts in lib/sidekiq\_unique\_jobs/lua have been rewritten to streamline the lock lifecycle, reduce Redis command overhead, and improve reliability. The new lock and unlock logic uses sorted sets for digest tracking with scores based on expiration time, enabling faster cleanup and preventing premature removal of lock information. A new ack script handles job acknowledgment with specific logic for different lock types, while a dedicated unlock script ensures primed keys are correctly removed. Additionally, a new recover script allows for the safe recovery of jobs from failed workers by scanning working queues and returning jobs to their original queues if the worker is no longer alive. These changes collectively enhance performance and robustness for unique job enforcement.
_lib/sidekiq\_unique\jobs/lua · high confidence
Refactored Lua script execution into a dedicated Script module
The internal mechanism for loading, caching, and executing Redis Lua scripts has been restructured into a new \SidekiqUniqueJobs::Script\ namespace. This change introduces a \Client\ class that manages script execution with automatic retry logic for transient errors (such as NOSCRIPT or BUSY states) and a \Scripts\ collection that handles thread-safe, lazy loading of scripts from disk into Redis. Additionally, a \Caller\ module provides a simplified interface for invoking scripts, while a \LuaError\ class now provides clearer error messages and backtraces when Lua scripts fail, improving debuggability for users.
_lib/sidekiq\_unique\jobs/script · high confidence
Refactored Lua shared utilities for performance and Sidekiq 7 compatibility
The Lua scripts in the shared library have been rewritten to improve performance and support Sidekiq v7. Key changes include replacing deprecated global argument handling with explicit \{...}\ in debug logging, implementing pagination for Redis commands (LRANGE, SSCAN, ZSCAN) to prevent blocking on large datasets, and optimizing digest lookups by caching string transformations. The code also introduces helper functions for parsing version strings and retrieving the current time, ensuring more robust handling of job reaping and active worker detection.
_lib/sidekiq\_unique\jobs/lua/shared · high confidence
Refactored Sidekiq Web UI helpers for v9 and Sidekiq 8 compatibility
The Sidekiq web interface helpers have been updated to support the v9 architecture and Sidekiq 8. This change removes the separate changelog and expiring digests views, merging expiring digests into the main digests collection and removing the changelog entirely. It also introduces robust time parsing and display helpers that handle various timestamp formats safely, ensuring compatibility with newer Sidekiq versions without requiring compatibility shims.
_lib/sidekiq\_unique\jobs/web · high confidence
Refactored locking strategy into a modular class hierarchy with client/server validation
The locking logic in \lib/sidekiq\_unique\_jobs/lock\ has been restructured from a monolithic implementation into a clear class hierarchy (\BaseLock\, \UntilExecuted\, \UntilExecuting\, \WhileExecuting\, \UntilAndWhileExecuting\, \UntilExpired\) to separate concerns between client-side queuing and server-side execution. This change introduces dedicated \ClientValidator\ and \ServerValidator\ classes that enforce valid conflict strategies (e.g., preventing \:replace\ on the server or \:raise\/\:reject\/\:reschedule\ on the client) and handles deprecation warnings for legacy \unique:\ keys. For users, this means more robust lock management that prevents duplicate executions during retries and provides clearer configuration errors if incompatible lock options are set.
_lib/sidekiq\_unique\jobs/lock · high confidence
Restored Ruby-based orphan reaper to prevent premature job deletion
The orphan reaper logic has been restored as a Ruby-based implementation to ensure that active jobs are not incorrectly identified as orphans and deleted. This change introduces a reaper that validates candidate digests against Sidekiq queues, the retry set, the scheduled set, and active processes before removal, short-circuiting on the first match to avoid false positives. It also includes safeguards such as a grace period and queue-length thresholds to prevent performance issues during high load, ensuring that only truly stale locks are cleaned up.
_lib/sidekiq\_unique\jobs/orphans · high confidence
Test coverage
Added Redis testing support module; Added custom RSpec matchers for date validation and Sidekiq queue assertions; Added integration test for lock behavior under high latency; Added performance benchmarks for lock digest, locksmith, and conflict replacement; Added shared RSpec contexts for testing Sidekiq and Locksmith integration; Added shared test examples for lock and worker behavior; Added test coverage for lock implementations and validation logic; Added test coverage for on-conflict strategies; Added test coverage for the Sidekiq Lua script execution layer; Added test coverage for worker locking and uniqueness behaviors; Added test suite for client middleware and test configuration; Added test support for unique job execution; Added test support infrastructure for Lua scripts and lock simulation; Added test worker fixtures for unique locking strategies; Added tests for Sidekiq API and job lifecycle uniqueness lock cleanup; Added tests for Sidekiq Unique Jobs web helpers; Added tests for Sidekiq job fetch and lock validation logic; Added tests for the Ruby-based orphan reaper; Expanded test coverage for Sidekiq Unique Jobs core components; Removal of legacy test helper configuration; Removed test\_client.rb test file.
Dependencies
Add Appraisal gemfiles for Sidekiq 8.0 and 8.1 compatibility testing
New Appraisal gemfiles have been added to explicitly test the library against Sidekiq versions 8.0 and 8.1. This enables the project to verify compatibility and run tests against these specific major versions of the Sidekiq dependency, supporting the transition from the Sidekiq 8 beta to the released versions.
gemfiles · high confidence
Upgrade to Rails 8.1 and Sidekiq 8+ with modern frontend tooling
The documentation site and example application have been upgraded to Rails 8.1.3, replacing the legacy Rails 3.2 stack. The \sidekiq-unique-jobs\ gem now requires Sidekiq 8 (supporting versions \< 10) and mandates Ruby 3.2+, dropping support for older Ruby and Sidekiq versions. Frontend tooling has been modernized to use Tailwind CSS v4 and DaisyUI v5, with the example app utilizing Bun for asset compilation. Development dependencies have been updated to include security auditing tools like Brakeman and Bundler-audit, and the gemspec has been updated to reflect the new runtime dependencies (concurrent-ruby, thor) and metadata.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 62.
Lenses
- Code Health 71
- Architecture 94
- Maturity 70
- Readiness 66
- Security 76
- Domain Modelling 100
- Accessibility 52
Changes since last survey
- 300 commits — 237 feature/other, 63 fixes
By area
- lib/sidekiq_unique_jobs — 128 commits
- (root) — 99 commits
- .github/workflows — 21 commits
- spec/sidekiq_unique_jobs — 20 commits
- myapp/package-lock.json — 6 commits
- myapp/app — 4 commits
- .claude/commands — 3 commits
- doc/SidekiqUniqueJobs — 3 commits
- docs/app — 2 commits
- docs/index.md — 2 commits
- spec/support — 2 commits
- (repo) — 1 commit
- .github/FUNDING.yml — 1 commit
- .github/dependabot.yml — 1 commit
- docs/Gemfile — 1 commit
- docs/_config.yml — 1 commit
- docs/config — 1 commit
- lib/tasks — 1 commit
- myapp/Gemfile — 1 commit
- myapp/yarn.lock — 1 commit
Notable commits
- fix: Documentation fixes (#622)
- fix: Fix CI status badge (#802)
- fix: Fix Sidekiq 8 unique jobs tab paths (#961)
- fix: Fix Sidekiq::Worker.clear_all override not being applied (#714)
- fix: Fix Testing Instructions (#827)
- fix: Fix active worker detection by using correct keys (#756)
- fix: Fix badges
- fix: Fix comment about successful reschedule (#875)
- fix: Fix drift (#688)
- fix: Fix example url in documentation (#596)
- fix: Fix handling of lock timeout (#619)
- fix: Fix homepage url (#667)
- fix: Fix ignored custom lock prefix (#886)
- fix: Fix instance level after_unlock callback (#737)
- fix: Fix numerous small issues with locking (#616)
- fix: Fix recording lock_info (#599)
- fix: Fix rubocop failure by expecting array to be empty (#784)
- fix: Fix ruby reaper edge case (#661)
- fix: Fix spec
- fix: Fix the remaining deprecation warnings (#681)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
zoolutions/sidekiq-unique-jobs was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 74882fe7b3c048ac86714610bb897bbc6e8c5344 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.