Module: Wurk::Middleware::CurrentAttributes

Defined in:
lib/wurk/middleware/current_attributes.rb

Overview

Propagates ActiveSupport::CurrentAttributes from the enqueueing process into the worker. Off by default — host opts in by calling Wurk::Middleware::CurrentAttributes.persist(klass_or_array).

One registered class → job hash key "cattr". Multiple → "cattr", "cattr_1", "cattr_2", … (keys mirror Sidekiq's naming exactly: wire-compat sacred).

Classes are kept by name and resolved per job, as a String registered from an initializer has to be. It also means a class object passed here doesn't go stale once development code reloading replaces the constant.

Spec: docs/target/sidekiq-free.md §10.3 and §2.2.

Defined Under Namespace

Classes: Load, Save

Constant Summary collapse

PERSISTENT_KEY =
'cattr'

Class Method Summary collapse

Class Method Details

.key_for(index) ⇒ Object

Composes the wire key for the Nth registered class. Sidekiq numbers from 1 ("cattr_1"); index 0 keeps the bare "cattr" key.



48
49
50
# File 'lib/wurk/middleware/current_attributes.rb', line 48

def key_for(index)
  index.zero? ? PERSISTENT_KEY : "#{PERSISTENT_KEY}_#{index}"
end

.persist(klass_or_array, config = Wurk.configuration) ⇒ Object

Register one or more CurrentAttributes classes. Re-registering is a no-op: add already dedupes by klass, so calling persist twice with the same set replaces the old entry with the new args.

Raises:

  • (ArgumentError)


27
28
29
30
31
32
33
34
35
# File 'lib/wurk/middleware/current_attributes.rb', line 27

def persist(klass_or_array, config = Wurk.configuration)
  classes = Array(klass_or_array).map { |klass| reference_for(klass) }
  raise ArgumentError, 'persist requires at least one CurrentAttributes class' if classes.empty?

  config.client_middleware.add(Save, classes)
  config.client_middleware.add(Load, classes)
  # Outermost, so every other server middleware sees the job's attributes.
  config.server_middleware.prepend(Load, classes)
end

.reference_for(klass) ⇒ Object

An anonymous class has no name to look up again, so it stays as given.



38
39
40
# File 'lib/wurk/middleware/current_attributes.rb', line 38

def reference_for(klass)
  klass.is_a?(Module) ? klass.name || klass : klass.to_s
end

.resolve(reference) ⇒ Object



42
43
44
# File 'lib/wurk/middleware/current_attributes.rb', line 42

def resolve(reference)
  reference.is_a?(String) ? Object.const_get(reference) : reference
end

.restore(klass, attrs) ⇒ Object



61
62
63
# File 'lib/wurk/middleware/current_attributes.rb', line 61

def restore(klass, attrs)
  attrs&.each { |name, value| klass.public_send("#{name}=", value) }
end

.snapshot(klass) ⇒ Object

AS::CurrentAttributes#attributes returns a HashWithIndifferentAccess; we coerce to a plain Hash so JSON encoding is predictable. .dup so the snapshot is a detached copy — Load holds onto the pre-job state and must not see it mutated when it restores the job's attributes, and Save must not alias live attributes into the persisted job hash.



57
58
59
# File 'lib/wurk/middleware/current_attributes.rb', line 57

def snapshot(klass)
  klass.attributes.to_h.dup
end