Skip to content

feat: ActiveJob Support#42

Draft
arturictus wants to merge 1 commit into
mainfrom
active_job
Draft

feat: ActiveJob Support#42
arturictus wants to merge 1 commit into
mainfrom
active_job

Conversation

@arturictus

Copy link
Copy Markdown
Owner

This pull request introduces a major refactor to RubyReactor's async execution infrastructure, adding first-class support for ActiveJob as an alternative to Sidekiq. The changes abstract the async backend, unify configuration, and implement adapter-specific worker, router, and sweeper classes for both ActiveJob and Sidekiq. This enables RubyReactor to run on any ActiveJob-compatible backend (e.g., inline, test, or other queueing systems), not just Sidekiq, while maintaining backward compatibility. Additionally, configuration is generalized and deprecated Sidekiq-specific settings are aliased.

Key changes include:

ActiveJob Adapter Implementation:

  • Added ActiveJob adapter with Worker, SweeperWorker, MapElementWorker, MapCollectorWorker, and Router classes, mirroring the Sidekiq structure and normalizing the async API (perform_async, perform_in). [1] [2] [3] [4] [5] [6]
  • Introduced Compat module to provide Sidekiq-style async methods on ActiveJob jobs.

Sidekiq Adapter Refactor:

  • Moved Sidekiq worker, router, and sweeper classes into a dedicated adapter namespace, mirroring the new ActiveJob structure. [1] [2] [3] [4] [5]

Configuration Unification and Backward Compatibility:

  • Generalized configuration keys: replaced sidekiq_queue and sidekiq_retry_count with queue_name and job_retry_count, providing deprecated aliases for backward compatibility. [1] [2]
  • async_router now defaults to the new Sidekiq adapter router class.

Core Library Integration:

  • Dynamically loads ActiveJob if available and uses the configured async adapter for sweeper scheduling, rather than hardcoding Sidekiq. [1] [2]
  • Updated internal references and comments to reflect the new adapter structure.

Test Support:

  • Added RSpec helpers for ActiveJob and async testing, and ensured test queues are cleared between examples. [1] [2]

These changes make RubyReactor's async execution backend-agnostic, more configurable, and easier to extend to other queueing systems in the future.

- Renamed and moved Sidekiq-related classes to RubyReactor::Adapters::Sidekiq namespace.
- Introduced RubyReactor::Adapters::ActiveJob namespace with corresponding worker classes.
- Updated configuration to allow switching between Sidekiq and ActiveJob.
- Refactored job processing logic to be framework-agnostic, extracting shared functionality into a new RubyReactor::Worker module.
- Adjusted tests to accommodate the new structure and ensure compatibility with both Sidekiq and ActiveJob.
- Added documentation for the new ActiveJob integration and configuration options.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors RubyReactor’s async execution to be adapter-based, adding first-class ActiveJob support alongside Sidekiq while keeping existing Sidekiq behavior working through a renamed/relocated adapter API.

Changes:

  • Introduces RubyReactor::Worker and RubyReactor::SweeperJob shared logic, then wires them into Adapters::Sidekiq::* and Adapters::ActiveJob::*.
  • Migrates Sidekiq classes from SidekiqWorkers/* + SidekiqAdapter to Adapters::Sidekiq/* and adds Adapters::ActiveJob/* equivalents (router + workers).
  • Unifies configuration keys (queue_name, job_retry_count) with deprecated aliases for Sidekiq-specific names; updates specs and adds ActiveJob-specific test helpers/specs.

Reviewed changes

Copilot reviewed 51 out of 52 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
specs/active_job.md Design/implementation notes for pluggable async adapters.
spec/spec_helper.rb Updates test configuration to use the new Sidekiq router namespace.
spec/single_worker_map_spec.rb Updates Sidekiq worker constant references to Adapters::Sidekiq::*.
spec/ruby_reactor/telemetry_spec.rb Updates drained worker constants to new adapter namespace.
spec/ruby_reactor/sweeper_entrypoints_spec.rb Updates sweeper require/constant to Adapters::Sidekiq::SweeperWorker.
spec/ruby_reactor/step/map_step_spec.rb Updates router class double to Adapters::Sidekiq::Router.
spec/ruby_reactor/map/dispatcher_spec.rb Updates router class double to Adapters::Sidekiq::Router.
spec/ruby_reactor/integration/ordered_lock_spec.rb Updates Sidekiq worker references for ordered-lock integration tests.
spec/ruby_reactor/integration/locking_spec.rb Updates Sidekiq worker references for locking integration tests.
spec/ruby_reactor/async_notification_interrupt_spec.rb Updates comments and router/worker constants to new adapter namespace.
spec/ruby_reactor/adapters/sidekiq/worker_spec.rb Moves/renames Sidekiq worker spec to adapter namespace.
spec/ruby_reactor/adapters/sidekiq/sweeper_worker_spec.rb Moves/renames Sidekiq sweeper spec to adapter namespace.
spec/ruby_reactor/adapters/active_job/worker_spec.rb Adds ActiveJob worker wiring tests.
spec/ruby_reactor/adapters/active_job/sweeper_worker_spec.rb Adds ActiveJob sweeper worker tests for scheduling/chain behavior.
spec/ruby_reactor/adapters/active_job/router_spec.rb Adds ActiveJob router end-to-end smoke tests.
spec/ruby_reactor/adapters/active_job/compat_spec.rb Adds tests for Sidekiq-style enqueue compat helpers on ActiveJob jobs.
spec/ruby_reactor_spec.rb Updates stubs to reference Adapters::Sidekiq::Router.
spec/map/map_recovery_spec.rb Updates router + Sidekiq map worker references to adapter namespace.
spec/map/map_fail_fast_spec.rb Updates Sidekiq worker references to adapter namespace.
spec/map/map_batch_size_spec.rb Updates router + Sidekiq map worker references to adapter namespace.
spec/map/map_async_retry_spec.rb Updates Sidekiq map worker references to adapter namespace.
spec/map/async_map_execution_spec.rb Updates router + Sidekiq map worker references to adapter namespace.
spec/examples/data_pipeline_spec.rb Updates router + Sidekiq map worker references to adapter namespace.
spec/async_retry_integration_spec.rb Updates router + Sidekiq worker references to adapter namespace.
lib/ruby_reactor/worker.rb New shared resume/snooze/escalate logic extracted from Sidekiq worker.
lib/ruby_reactor/sweeper_job.rb New shared self-rescheduling sweeper tick logic for adapters.
lib/ruby_reactor/sidekiq_workers/worker.rb Removes old Sidekiq worker implementation (moved to adapter + shared module).
lib/ruby_reactor/sidekiq_workers/sweeper_worker.rb Removes old Sidekiq sweeper implementation (moved to adapter + shared module).
lib/ruby_reactor/sidekiq_workers/map_element_worker.rb Removes old Sidekiq map element worker (moved to adapter).
lib/ruby_reactor/sidekiq_workers/map_collector_worker.rb Removes old Sidekiq map collector worker (moved to adapter).
lib/ruby_reactor/sidekiq_adapter.rb Removes old Sidekiq router (replaced by Adapters::Sidekiq::Router).
lib/ruby_reactor/rspec/test_subject.rb Generalizes async job processing in tests to Sidekiq or ActiveJob.
lib/ruby_reactor/rspec/sidekiq_helpers.rb Updates worker class list to adapter namespace.
lib/ruby_reactor/rspec/async_test_helpers.rb Adds adapter-agnostic async test detection/drain entrypoint.
lib/ruby_reactor/rspec/active_job_helpers.rb Adds ActiveJob :test adapter drain/pending job helpers.
lib/ruby_reactor/rspec.rb Loads new ActiveJob helpers and clears ActiveJob queues between examples.
lib/ruby_reactor/map/element_executor.rb Updates inline-async comment to reference shared worker module.
lib/ruby_reactor/configuration.rb Adds queue_name/job_retry_count + deprecated Sidekiq aliases; updates default router.
lib/ruby_reactor/adapters/sidekiq/worker.rb New Sidekiq worker wiring that includes shared RubyReactor::Worker.
lib/ruby_reactor/adapters/sidekiq/sweeper_worker.rb New Sidekiq sweeper wiring that includes shared RubyReactor::SweeperJob.
lib/ruby_reactor/adapters/sidekiq/router.rb New Sidekiq router implementing the async router contract.
lib/ruby_reactor/adapters/sidekiq/map_element_worker.rb New Sidekiq map element worker in adapter namespace.
lib/ruby_reactor/adapters/sidekiq/map_collector_worker.rb New Sidekiq map collector worker in adapter namespace.
lib/ruby_reactor/adapters/active_job/worker.rb New ActiveJob worker wiring that includes shared RubyReactor::Worker + retry/queue settings.
lib/ruby_reactor/adapters/active_job/sweeper_worker.rb New ActiveJob sweeper wiring that includes shared RubyReactor::SweeperJob.
lib/ruby_reactor/adapters/active_job/router.rb New ActiveJob router implementing the async router contract.
lib/ruby_reactor/adapters/active_job/map_element_worker.rb New ActiveJob map element worker in adapter namespace.
lib/ruby_reactor/adapters/active_job/map_collector_worker.rb New ActiveJob map collector worker in adapter namespace.
lib/ruby_reactor/adapters/active_job/compat.rb Adds Sidekiq-style perform_async/perform_in helpers for ActiveJob jobs.
lib/ruby_reactor.rb Optionally requires ActiveJob and routes sweeper scheduling via the configured adapter.
Gemfile.lock Adds ActiveJob and updates the resolved Rails-related dependency set.
Gemfile Adds activejob dependency for development/test usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +34 to +47
# If reactor_class_name is provided, use it to get the reactor class
# This handles cases where the class can't be found via const_get
if reactor_class_name && context.reactor_class.nil?
begin
context.reactor_class = Object.const_get(reactor_class_name)
rescue NameError
# If not found, try to find it in the current namespace
# This is a fallback for test environments
context.reactor_class = reactor_class_name.constantize if reactor_class_name.respond_to?(:constantize)
end
end

# Mark that we're executing inline to prevent nested async calls
context.inline_async_execution = true
Comment thread lib/ruby_reactor.rb
Comment on lines +373 to 377
def self.sweeper_job_class
router = configuration.async_router
namespace = Object.const_get(router.name.rpartition("::").first)
namespace.const_get(:SweeperWorker)
end
Comment thread specs/active_job.md
Comment on lines +14 to +16
- `RubyReactor.configuration.async_router` (default `RubyReactor::SidekiqAdapter`,
[configuration.rb:106-108](../lib/ruby_reactor/configuration.rb#L106-L108)) is the
only thing the core engine calls to go async. Call sites:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants