feat(config): add global on_conflict setting#936
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 7 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughA global Changes
Poem
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
lib/sidekiq_unique_jobs/config.rb (1)
149-150: Consider validatingon_conflictassignments at config-write time.Right now any object can be assigned and invalid values will fail later during strategy resolution. A small setter guard would fail fast and improve operator feedback.
Suggested hardening
class Config < ThreadSafeConfig + def on_conflict=(value) + case value + when nil, Symbol + super + when Hash + normalized = value.transform_keys(&:to_sym) + invalid_keys = normalized.keys - %i[client server] + raise ArgumentError, "Invalid on_conflict keys: #{invalid_keys.inspect}" if invalid_keys.any? + + super(normalized) + else + raise ArgumentError, "Invalid on_conflict: #{value.inspect} (expected Symbol, Hash, or nil)" + end + end + def initialize(*) super🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/sidekiq_unique_jobs/config.rb` around lines 149 - 150, Add validation when assigning the global on_conflict configuration: replace direct writes to the ON_CONFLICT constant with a Config#on_conflict= setter (or add validation in the existing setter) that accepts nil or only the known strategy types used by the strategy resolver and raises ArgumentError on invalid inputs; reference the ON_CONFLICT constant and the on_conflict= setter so the check mirrors the values handled by your conflict resolution logic (e.g., the same list used by the resolver method) and include a clear error message so invalid assignments fail fast.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@spec/sidekiq_unique_jobs/lock_config_spec.rb`:
- Around line 154-172: The temporary config overrides in the specs using
SidekiqUniqueJobs.use_config should also disable uniqueness; update the
use_config blocks (where SidekiqUniqueJobs.use_config is called and
described_class.from_worker is invoked) to include enabled: false (or set
SidekiqUniqueJobs.config.enabled = false within the block) so these examples
focus on config resolution and not uniqueness behavior.
---
Nitpick comments:
In `@lib/sidekiq_unique_jobs/config.rb`:
- Around line 149-150: Add validation when assigning the global on_conflict
configuration: replace direct writes to the ON_CONFLICT constant with a
Config#on_conflict= setter (or add validation in the existing setter) that
accepts nil or only the known strategy types used by the strategy resolver and
raises ArgumentError on invalid inputs; reference the ON_CONFLICT constant and
the on_conflict= setter so the check mirrors the values handled by your conflict
resolution logic (e.g., the same list used by the resolver method) and include a
clear error message so invalid assignments fail fast.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 208563e9-dc0b-426a-88f9-3209ce309004
📒 Files selected for processing (4)
lib/sidekiq_unique_jobs/config.rblib/sidekiq_unique_jobs/lock_config.rbspec/sidekiq_unique_jobs/config_spec.rbspec/sidekiq_unique_jobs/lock_config_spec.rb
| SidekiqUniqueJobs.use_config(on_conflict: :reject) do | ||
| config = described_class.from_worker(item) | ||
| expect(config.on_conflict).to eq(:reject) | ||
| end | ||
| end | ||
|
|
||
| it "supports hash values from global config" do | ||
| SidekiqUniqueJobs.use_config(on_conflict: { client: :log, server: :reject }) do | ||
| config = described_class.from_worker(item) | ||
| expect(config.on_client_conflict).to eq(:log) | ||
| expect(config.on_server_conflict).to eq(:reject) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| context "when set per-job and global config also has on_conflict" do | ||
| it "prefers per-job config" do | ||
| SidekiqUniqueJobs.use_config(on_conflict: :reject) do | ||
| config = described_class.from_worker(item) |
There was a problem hiding this comment.
Add enabled: false to these temporary config overrides.
These examples validate config resolution, not uniqueness behavior, so the use_config overrides should disable uniqueness to align with test-suite convention.
Suggested test adjustment
- SidekiqUniqueJobs.use_config(on_conflict: :reject) do
+ SidekiqUniqueJobs.use_config(on_conflict: :reject, enabled: false) do
config = described_class.from_worker(item)
expect(config.on_conflict).to eq(:reject)
end
end
it "supports hash values from global config" do
- SidekiqUniqueJobs.use_config(on_conflict: { client: :log, server: :reject }) do
+ SidekiqUniqueJobs.use_config(on_conflict: { client: :log, server: :reject }, enabled: false) do
config = described_class.from_worker(item)
expect(config.on_client_conflict).to eq(:log)
expect(config.on_server_conflict).to eq(:reject)
end
end
@@
- SidekiqUniqueJobs.use_config(on_conflict: :reject) do
+ SidekiqUniqueJobs.use_config(on_conflict: :reject, enabled: false) do
config = described_class.from_worker(item)
expect(config.on_conflict).to eq(:log)
end🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@spec/sidekiq_unique_jobs/lock_config_spec.rb` around lines 154 - 172, The
temporary config overrides in the specs using SidekiqUniqueJobs.use_config
should also disable uniqueness; update the use_config blocks (where
SidekiqUniqueJobs.use_config is called and described_class.from_worker is
invoked) to include enabled: false (or set SidekiqUniqueJobs.config.enabled =
false within the block) so these examples focus on config resolution and not
uniqueness behavior.
There was a problem hiding this comment.
Not if I want to actually test uniqueness :) which is most of the time
There was a problem hiding this comment.
@mhenrixon, you're absolutely right — these tests are directly exercising the on_conflict config resolution behavior, which is core to uniqueness. Adding enabled: false here would undermine what the tests are validating. My suggestion was incorrect. Apologies for the noise!
✏️ Learnings added
Learnt from: mhenrixon
Repo: mhenrixon/sidekiq-unique-jobs PR: 936
File: spec/sidekiq_unique_jobs/lock_config_spec.rb:154-172
Timestamp: 2026-03-27T23:18:05.968Z
Learning: In `spec/sidekiq_unique_jobs/lock_config_spec.rb`, tests under `describe "#on_conflict"` that use `SidekiqUniqueJobs.use_config(on_conflict: ...)` blocks should NOT add `enabled: false`, because they are intentionally testing uniqueness/conflict resolution behavior. The `enabled: false` pattern is only for tests that are unrelated to uniqueness behavior.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/spec/**/*.rb : In tests, use `SidekiqUniqueJobs.use_config` to temporarily override config and `SidekiqUniqueJobs.config.enabled = false` to disable uniqueness when not testing it
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/sidekiq_unique_jobs/on_conflict/*strategy.rb : Conflict resolution strategies must inherit from `SidekiqUniqueJobs::OnConflict::Strategy`
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/spec/sidekiq_unique_jobs/lock/**/*_spec.rb : Integration tests for lock types should be placed in `spec/sidekiq_unique_jobs/lock/*_spec.rb` and cover end-to-end behavior
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/sidekiq_unique_jobs/lock/?(base_lock|*_lock).rb : Lock implementations must inherit from `SidekiqUniqueJobs::Lock::BaseLock` and implement `lock` and `execute` methods
Learnt from: mhenrixon
Repo: mhenrixon/sidekiq-unique-jobs PR: 929
File: myapp/spec/requests/home_spec.rb:5-33
Timestamp: 2026-03-27T18:36:07.940Z
Learning: In the `myapp/` test suite, request specs that only assert HTTP response status codes and rendered body content (e.g., `myapp/spec/requests/`) do NOT need `SidekiqUniqueJobs.use_config { |c| c.enabled = false }` wrapping. That pattern is only appropriate for specs that actually enqueue jobs or exercise Redis lock/uniqueness behavior. Applying it to pure controller rendering specs is misleading and implies a coupling that does not exist.
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/sidekiq_unique_jobs/{lock,middleware,orphans}/**/*.rb : The gem uses `redis-client` (not `redis` gem) via Sidekiq's connection pool; use wrapper classes in `lib/sidekiq_unique_jobs/redis/` for object-oriented Redis interfaces
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Reflection hooks should be used for observability via `SidekiqUniqueJobs.reflect` to track events like locked, lock_failed, unlocked, unlock_failed, timeout, and execution_failed
Learnt from: mhenrixon
Repo: mhenrixon/sidekiq-unique-jobs PR: 929
File: myapp/app/controllers/locks_controller.rb:4-4
Timestamp: 2026-03-27T18:35:37.818Z
Learning: The `myapp/` directory in the `mhenrixon/sidekiq-unique-jobs` repository is a localhost-only development and testing application used exclusively for debugging the sidekiq-unique-jobs gem during development. It is never deployed or exposed to the internet. CSRF protection skips (e.g., `skip_before_action :verify_authenticity_token`) and other security relaxations in this app are acceptable and intentional for developer tooling convenience.
Learnt from: CR
Repo: mhenrixon/sidekiq-unique-jobs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-27T17:12:26.401Z
Learning: Applies to **/sidekiq_unique_jobs/{middleware,lock}/**/*.rb : All Redis operations must use Lua scripts located in `lib/sidekiq_unique_jobs/lua/` to ensure atomic operations and consistency
Learnt from: mhenrixon
Repo: mhenrixon/sidekiq-unique-jobs PR: 929
File: myapp/app/assets/stylesheets/application.tailwind.css:4-21
Timestamp: 2026-03-27T18:35:38.315Z
Learning: In the sidekiq-unique-jobs repository, the root `.stylelintrc.json` belongs to the parent gem project only. The `myapp/` subdirectory (test app) has its own separate tooling configuration. As of PR `#929`, Stylelint (`stylelint.config.js`) was removed from `myapp/` entirely, so Stylelint lint errors reported against files under `myapp/` (e.g., `myapp/app/assets/stylesheets/`) are false positives and should not be flagged.
Adds `on_conflict` to the global configuration, allowing a default
conflict resolution strategy without specifying it on every job:
SidekiqUniqueJobs.configure do |config|
config.on_conflict = :log
end
Supports both symbol and hash (client/server) values. Per-job
`on_conflict` in sidekiq_options takes precedence over the global
default.
Closes #865
c83a45c to
0dd2bdd
Compare
Summary
on_conflictto global configuration as a default for all jobs:log,:reject, etc.) and hash values ({ client: :log, server: :reject })on_conflictinsidekiq_optionstakes precedence over the global defaultUsage
Closes #865
Test plan
Summary by CodeRabbit
New Features
on_conflictconfiguration option to define a default conflict resolution strategy for jobs.Tests
on_conflictconfiguration and its precedence behavior.