Repository navigation
Redesign enqueue API: auto-registry + named-parameter jobs - #27
Merged
Merged
Conversation
Closes #25 and #26 — one API redesign in two halves. Auto-registry (#25): Benchwarmer::Job.inherited registers each named subclass under its job_type in Benchwarmer::Job.registry. Queue, Worker, and Web default their registry to this global hash, so consuming apps never build one by hand; an explicit registry: still overrides it (the injected-registry test seam and per-app isolation both keep working). Anonymous classes (Class.new(Job)) have no name and are skipped. Named parameters (#26): base Job#initialize(**params) captures constructor kwargs. Queue#enqueue now accepts a Job class (positional args:), a Job instance (its kwargs become the payload), or a type string. Instance kwargs serialize into the args column as a JSON object; args: arrays serialize as JSON arrays. The worker parses the payload and dispatches Array -> perform(*args), Object -> perform(**symbolized). Args must be JSON-serializable — non-native values raise ArgumentError at enqueue time (JSON strict mode) instead of failing inside the worker. Ripple effects: Job#enqueue_child and Queue#schedule (type: accepts a class) get the same flexibility; retry copies args verbatim so object payloads round-trip; the web enqueue form accepts a JSON array OR object (422 only for a bare scalar) and defaults its registry to the auto-registry via a deferred read so late-defined jobs appear. examples/, tasks/dev.rake, and README updated to the new API — no hand-built registry anywhere. Breaking changes (pre-1.0): - Worker.new/Queue.new registry: is now optional (defaults to the global auto-registry) rather than required. - Queue#enqueue's first positional arg is now a class/instance/string (was a type string only) — strings still work. - Enqueue args are validated with JSON strict mode: values that aren't JSON-native (arbitrary objects, Time, Proc) now raise ArgumentError at enqueue time instead of being silently coerced to strings. Co-Authored-By: Claude Opus 4.8 <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.
Reworks the user-facing enqueue API so consuming apps never touch a registry and jobs can carry named parameters. Two halves of one redesign.
Auto-registry (#25)
Benchwarmer::Job.inheritedregisters every named subclass under itsjob_typeinBenchwarmer::Job.registry.Queue,Worker, andWebdefault theirregistryto this global hash, so a consuming app just defines job classes. An explicitregistry:/:registrystill overrides it, preserving the injected-registry test seam and per-app isolation. Anonymous classes (Class.new(Job)) have no name and are skipped.Named parameters (#26)
Base
Job#initialize(**params)captures constructor kwargs.Queue#enqueuenow accepts:enqueue(GreetJob, args: ["world"])(positional args)enqueue(GreetJob.new(name: "World"))(its kwargs become the payload)enqueue("greet", args: {name: "World"})(how the web form submits)Instance kwargs serialize into the
argscolumn as a JSON object;args:arrays serialize as JSON arrays. The worker parses the payload and dispatchesArray -> perform(*args),Object -> perform(**symbolized). The instance is a value object describing the run; the worker rebuilds fresh viajob_factoryand passes params toperform(collaborators stay DI viainitialize, params are data).Args must be JSON-serializable — non-native values raise
ArgumentErrorat enqueue time (JSON strict mode) rather than failing inside the worker. Symbols still round-trip (kwargs survive).Ripple effects
Job#enqueue_childandQueue#schedule(type:accepts a class) get the same flexibility.queue.retrycopies args verbatim, so object payloads round-trip (tested).examples/,tasks/dev.rake, andREADME.mdrewritten to the new API — no hand-built registry anywhere.Breaking changes (pre-1.0)
Worker.new/Queue.newregistry:is now optional (defaults to the global auto-registry) rather than required.Queue#enqueue's first positional arg is now a class/instance/string (was a type string only) — strings still work.Time,Proc) now raiseArgumentErrorat enqueue time instead of being silently coerced to strings.Verification
bundle exec rake test— 126 runs, 417 assertions, 0 failures.bin/check(standardrb) — clean.rake dev:ui: enqueue form shows the new "Args (JSON array or object)" label; POSTing{"chunk":"abc"}object args enqueued successfully (stored{"chunk":"abc"}); a bare scalar42returned 422; graceful shutdown cleaned up the demo db.examples/bin/worker: schedulednightlyvia the class-basedtype: NightlyJoband polled cleanly; ran aGreetJob.new(name:...)instance end-to-end through a worker (perform(name:, language:)received the kwargs).Closes #25
Closes #26
🤖 Generated with Claude Code