Add Micro::Case::ActiveJob: async runner with rename-safe registry and DSL#151
Open
serradura wants to merge 1 commit into
Open
Add Micro::Case::ActiveJob: async runner with rename-safe registry and DSL#151serradura wants to merge 1 commit into
serradura wants to merge 1 commit into
Conversation
…d DSL Closes #2. Purely additive — no breaking changes to the public API. The new file is loaded via `require 'micro/case/active_job'`; the gemspec is unchanged, so `activejob` remains an optional, host-provided dependency. Public surface: - `Micro::Case.async` / `Micro::Case.later` — return a `Caller` that enqueues via a per-use-case `<UseCase>::Job` subclass. - `Micro::Case.active_job(&block)` — eager class macro evaluating the narrow DSL (`key`, `retry_on`, `discard_on`, `after_discard`, `default_options`, `around_perform`, `after_transaction_commit`). Unknown DSL methods raise `NoMethodError` for typo protection. - `Micro::Case::ActiveJob::Registry` — thread-safe key-to-class mapping so renaming a use case between enqueue and pickup no longer raises `NameError`. Auto-registers `klass.name` for day-one adoption. - `Micro::Case::ActiveJob::Caller` — merges DSL `default_options` with per-call `job_options` (explicit wins); `to_proc` for composition. - `Micro::Case::ActiveJob.batch(pairs)` — uses `perform_all_later` on Rails 7.1+; falls back to per-pair enqueue on older Rails. - `Micro::Case::ActiveJob::Error` / `UnknownKey` — documented rescue contracts. - `Micro::Case.config.strict_registry` (default false) — disables the `safe_constantize` fallback for registry misses. All argument checks introduced by the runner route through `Micro::Case::Check::Enabled` / `Disabled` (10 new methods, identical signatures on both modules) per the convention from 5.4.0. Test plan: 37 new tests under `test/micro/case/active_job*` cover basic enqueue, `job_options` threading, `raise_on_failure`, rename-via-registry, auto-registration, duplicate/unknown keys, DSL methods, typo protection, inheritance, batch, `to_proc` composition, strict mode, and the check toggle. `bundle exec rake test` and the Rails 8.1 appraisal pass green under both `ENABLE_TRANSITIONS=true|false`. `activejob` added to the default `Gemfile`'s test group and to every appraisal in `Appraisals` so the new suite runs under `rake test` and the full matrix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2.
Adds
Micro::Case::ActiveJob— a built-in, opt-in async runner. Purely additive; the public API ofu-casestays frozen and the gemspec is unchanged (activejobremains an optional, host-provided dependency).Summary
MyCase.async.call(input)/MyCase.later.call(input)— enqueue anyMicro::Casesubclass via ActiveJob. Per-use-case job subclass is built lazily and named<UseCase>::Jobso it serializes across enqueue/dequeue.active_job do … endclass macro — eager DSL evaluated at class-body load time. Narrow surface:key,retry_on,discard_on,after_discard,default_options,around_perform,after_transaction_commit. Unknown methods raiseNoMethodErrorwith the valid-method list for typo protection.Micro::Case::ActiveJob::Registry— thread-safeMutex-backed mapping of stable string keys to use-case classes. Auto-registersklass.name => klasson first call so day-one adopters don't need a DSL declaration. Explicitkey '…'makes renames safe: the payload carries the key, not the constant name.Micro::Case::ActiveJob.batch(pairs)— usesActiveJob.perform_all_lateron Rails 7.1+, falls back to per-pair enqueue on older Rails.Micro::Case::ActiveJob::Error(raised on the worker whenraise_on_failure: trueand the result is a failure; exposes.result) andMicro::Case::ActiveJob::UnknownKey(raised when a payload's key doesn't resolve).Micro::Case.config.strict_registry(defaultfalse) — disables thesafe_constantizefallback for registry misses.ActiveJob features exposed declaratively:
retry_on/discard_on(Rails 5.1+),after_discard(Rails 7.1+; logs once and no-ops on older Rails),enqueue_after_transaction_commitviaafter_transaction_commit :always|:never|:default(Rails 7.2+; logs + no-ops on older Rails),around_perform,default_options. GlobalID-coded inputs work transparently — the runner does not pre-coerce input on the worker side.All 10 new internal argument validations route through
Micro::Case::Check::Enabled/Disabled(matching the convention introduced in 5.4.0), so they participate inconfig.disable_runtime_checks = true.Open-question resolutions
Micro::Case::ActiveJob.batch(notMicro::Case.async_batch) — keepsMicro::Case's class-method namespace tight.default_options, and registered key. A subclass that redeclaresactive_job do … endmust use a fresh key — enforced by the registry's duplicate-key check.asynccall: enabled.job_options:wins over DSLdefault_options(matches Rails'setoverridingqueue_as).strict_registrydefault:false(friendlier for early adoption).Micro::Case::ActiveJob::DSL.lib/micro/case/active_job.rb).Test plan
bundle exec rake test— 832 runs, 8246 assertions, 0 failures.bundle exec appraisal rails-8-1 rake test— 1079 runs, 0 failures.ENABLE_TRANSITIONS=false bundle exec appraisal rails-8-1 rake test— 745 runs, 0 failures.activejob(corelib/micro/case.rbdoes not require any active_job code;check.rbonly adds methods, no AJ constant references).job_optionsthreading,raise_on_failure, rename-via-registry, auto-registration, duplicate/unknown keys, DSL methods (retry_on,default_options,around_perform, typo protection), inheritance, batch,to_proccomposition, strict mode, and the check toggle for each new method.bundle exec rake matrix) against the CI grid — recommended before merge.Out of scope (not bumped here)
CLAUDE.md, this would be a minor bump (purely additive, no dependency-floor change), but the bump is intentionally not done in this PR — release tagging is a human step. The CHANGELOG entry sits under[Unreleased]until then.🤖 Generated with Claude Code