@@ -44,15 +44,18 @@ bin/setup # Install dependencies
4444- Entry point module that classes extend to gain async capabilities
4545- Defines three simple methods: ` perform_async ` , ` perform_in(interval) ` , and ` perform_at(timestamp) `
4646- Each method returns an ` AsyncProxy ` instance configured for the appropriate scheduling mode
47- - No method wrapping or interception - just three straightforward class methods
47+ - Provides ` sidekiqable_options(options) ` method for per-class configuration
48+ - Options set per-class take precedence over global configuration
49+ - No method wrapping or interception - just straightforward class methods
4850
4951** ` Sidekiqable::AsyncProxy ` ** (lib/sidekiqable/async_proxy.rb)
5052- Simple proxy returned by ` perform_async ` , ` perform_in ` , and ` perform_at `
5153- Uses ` method_missing ` to catch the actual method call (e.g., ` .boo(1, 2) ` )
52- - Validates arguments are Sidekiq-serializable via ` Sidekiq.dump_json `
54+ - Validates arguments are Sidekiq-serializable via ` Sidekiq.dump_json ` (can be disabled)
5355- Raises error if blocks are passed (cannot be serialized)
5456- Enqueues job to ` Worker ` with compact payload format: ` ["ClassName.method_name", *args] `
55- - Applies global configuration options (queue, retry) before enqueuing
57+ - Applies configuration options before enqueuing using Sidekiq's ` .set() ` API
58+ - Configuration priority: per-class options > global options > Sidekiq defaults
5659
5760** ` Sidekiqable::Worker ` ** (lib/sidekiqable/worker.rb)
5861- Standard Sidekiq worker that executes scheduled method calls
@@ -62,8 +65,10 @@ bin/setup # Install dependencies
6265
6366** ` Sidekiqable::Configuration ` ** (lib/sidekiqable/configuration.rb)
6467- Global configuration object accessed via ` Sidekiqable.configuration `
65- - Supports ` queue ` and ` retry ` options applied to all jobs
66- - Returns hash of Sidekiq options for worker configuration
68+ - Supports all standard Sidekiq worker options: ` queue ` , ` retry ` , ` dead ` , ` backtrace ` , ` pool ` , ` tags `
69+ - Sidekiqable-specific option: ` validate_arguments ` (default: true)
70+ - Returns hash of Sidekiq options for worker configuration via ` sidekiq_options `
71+ - Can be configured via ` Sidekiqable.configure ` or Rails' ` config.sidekiqable `
6772
6873** ` Sidekiqable::Railtie ` ** (lib/sidekiqable/railtie.rb)
6974- Rails integration that exposes ` config.sidekiqable ` for environment-specific configuration
@@ -84,18 +89,83 @@ bin/setup # Install dependencies
84892 . Method executes immediately (no proxy involved)
85903 . Returns result directly
8691
92+ ### Configuration System
93+
94+ ** Three levels of configuration (in order of precedence):**
95+
96+ 1 . ** Per-class options** (highest priority) - Set via ` sidekiqable_options ` in the class
97+ ``` ruby
98+ class Foo
99+ extend Sidekiqable ::AsyncableMethods
100+ sidekiqable_options queue: ' high' , retry: 3
101+ end
102+ ```
103+
104+ 2 . ** Global configuration** - Set via ` Sidekiqable.configure ` or Rails ` config.sidekiqable `
105+ ``` ruby
106+ Sidekiqable .configure do |config |
107+ config.queue = ' default'
108+ config.retry = 5
109+ config.validate_arguments = true
110+ end
111+ ```
112+
113+ 3 . ** Sidekiq defaults** (lowest priority) - Used when not configured
114+
115+ ** Available options:**
116+ - Standard Sidekiq options: ` queue ` , ` retry ` , ` dead ` , ` backtrace ` , ` pool ` , ` tags `
117+ - Sidekiqable-specific: ` validate_arguments ` (enables/disables argument serialization validation)
118+
119+ ** How options are applied:**
120+ - ` AsyncProxy ` merges per-class and global options
121+ - Uses Sidekiq's ` .set() ` API to apply options: ` Worker.set(options).perform_async(...) `
122+ - This happens at enqueue time, not worker definition time
123+
87124### Implementation Notes
88125
89126- No method wrapping or hooks - just simple ` method_missing ` on proxy objects
90127- Compact payload format reduces serialization overhead
91128- Clear separation between sync and async code paths
92129- All complexity is isolated to the ` AsyncProxy ` class (~ 50 lines)
130+ - Configuration is applied dynamically at enqueue time, not on the Worker class itself
93131
94132## Testing Notes
95133
96- - Uses Minitest for testing
134+ - Uses Minitest for testing with Sidekiq test mode
97135- Test helper location: test/test_helper.rb
98- - Current test coverage is minimal (placeholder test exists in test/test_sidekiqable.rb)
136+ - Tests cover: version check, method presence, async enqueuing, delayed jobs, worker execution, block rejection, and sync calls
137+ - Run with ` rake test ` or ` bundle exec rake test `
138+
139+ ## Key Design Decisions
140+
141+ ### Why the current API: ` Foo.perform_async.bar(1, 2) ` ?
142+
143+ This syntax was chosen for clarity and simplicity:
144+ - ** Clear intent** : Starting with ` perform_async ` makes async behavior explicit
145+ - ** No method wrapping** : Avoids complex metaprogramming with ` singleton_method_added ` hooks
146+ - ** Familiar** : Similar to Sidekiq's standard ` Worker.perform_async ` pattern
147+ - ** Simple implementation** : Just 3 methods + proxy with ` method_missing ` (~ 60 total lines)
148+
149+ Alternative syntaxes considered:
150+ - ` Foo.bar(1, 2).perform_async ` - Requires wrapping ALL methods, adds overhead
151+ - ` Foo.async.bar(1, 2) ` - Similar to current, but less Sidekiq-like
152+ - ` Foo.bar_async(1, 2) ` - Requires suffix convention, less flexible
153+
154+ ### Why compact payload format: ` ["Foo.bar", 1, 2] ` ?
155+
156+ - ** Reduces serialization size** : One less array element per job
157+ - ** Cleaner Sidekiq UI** : Job args look more natural
158+ - ** No edge cases** : Method names can't contain dots in Ruby, so parsing is safe
159+
160+ Alternative considered:
161+ - ` ["Foo", "bar", 1, 2] ` - More structured but slightly larger payload
162+
163+ ### Why dynamic configuration via ` .set() ` ?
164+
165+ Configuration is applied at enqueue time using ` Worker.set(options) ` rather than defining ` sidekiq_options ` on the Worker class:
166+ - ** Flexibility** : Per-class options can override global config
167+ - ** Single worker** : One ` Worker ` class handles all jobs, options vary per caller
168+ - ** Standard Sidekiq pattern** : Uses ` .set() ` API that all Sidekiq users know
99169
100170## Ruby Version
101171
0 commit comments