Problem
bin/nebula_queue_worker:103:
handler_class.new.perform(**payload['args'].transform_keys(&:to_sym))
Two issues:
- Kwarg signature mismatch drops jobs. If a payload contains a key the handler doesn't declare (e.g., producer added
tracking_id: before consumer was deployed), perform raises ArgumentError: unknown keyword and the rescue at line 106 logs + drops it. No retry, no DLQ. Rolling deploys of producer → consumer will silently lose jobs.
transform_keys(&:to_sym) on arbitrary JSON. Modern Ruby GCs symbols, but combined with (1) this amplifies silent loss. Also, no schema validation — nothing rejects payloads missing required args or with wrong types; the error surfaces only at perform call time.
Fix
- Use
perform(**args, **_ignored) pattern, or explicitly filter the payload hash to the method signature (method(:perform).parameters) and log/reject unknown keys instead of dropping.
- Validate payload shape (
job, args, enqueued_at, retry_count) at fetch time; malformed payloads go straight to the dead set with a MalformedPayload reason.
- Pair with the retry/DLQ work — any handler exception (including
ArgumentError) must be retried, not dropped.
Acceptance
- Adding a new kwarg to a producer without restarting consumers does not lose jobs.
- Malformed payloads appear in a dead-letter / failed set, not just stderr.
Problem
bin/nebula_queue_worker:103:Two issues:
tracking_id:before consumer was deployed),performraisesArgumentError: unknown keywordand the rescue at line 106 logs + drops it. No retry, no DLQ. Rolling deploys of producer → consumer will silently lose jobs.transform_keys(&:to_sym)on arbitrary JSON. Modern Ruby GCs symbols, but combined with (1) this amplifies silent loss. Also, no schema validation — nothing rejects payloads missing required args or with wrong types; the error surfaces only atperformcall time.Fix
perform(**args, **_ignored)pattern, or explicitly filter the payload hash to the method signature (method(:perform).parameters) and log/reject unknown keys instead of dropping.job,args,enqueued_at,retry_count) at fetch time; malformed payloads go straight to the dead set with aMalformedPayloadreason.ArgumentError) must be retried, not dropped.Acceptance