Module: Pgbus::CurrentAttributes
- Defined in:
- lib/pgbus/current_attributes.rb
Overview
Persists ActiveSupport::CurrentAttributes across enqueue → perform (issue #430).
capture snapshots the assigned attributes of every persisted class
(config.current_attributes: :auto, an explicit list, or per-class
only:/except: filters) serialized through ActiveJob::Arguments — so
GlobalID models, Symbols, Times round-trip like job arguments and fall
under the allowed_global_id_models allowlist on the way back. An
attribute holding an unpersisted record is skipped with a debug log
(no id → no GlobalID → it could never be restored; see
#reject_unpersisted). restore nests klass.set(attrs) for the
duration of a block.
The ActiveJob side (Pgbus::ActiveJob::CurrentAttributes) calls capture
from serialize and restore around perform_now, so the hop works under
the pgbus worker and under Rails' :test / :inline adapters alike.
Constant Summary collapse
- METADATA_KEY =
"pgbus_current"
Class Method Summary collapse
-
.capture(config = Pgbus.configuration, override: nil) ⇒ Object
{ "Current" => serialized_attrs, ... } or nil when there is nothing to persist.
- .enabled?(config = Pgbus.configuration) ⇒ Boolean
-
.normalize(value) ⇒ Object
Config/override value → nil | :auto | [{ name:, only:, except: }].
-
.persisted_specs(config = Pgbus.configuration, override: nil) ⇒ Object
Normalized [{ name:, only:, except: }] for the config (or override).
-
.restore(stored, &block) ⇒ Object
Set every stored class's attributes for the block; previous values come back afterwards (ActiveSupport::CurrentAttributes#set semantics).
Class Method Details
.capture(config = Pgbus.configuration, override: nil) ⇒ Object
{ "Current" => serialized_attrs, ... } or nil when there is nothing
to persist. override is a per-job-class spec (false disables; an
Array/Hash replaces the config's list for this job).
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/pgbus/current_attributes.rb', line 33 def capture(config = Pgbus.configuration, override: nil) return nil if override == false return nil unless override || enabled?(config) captured = {} persisted_specs(config, override: override).each do |spec| klass = resolve_class(spec[:name]) or next attrs = reject_unpersisted(klass, filter_attrs(klass.attributes, spec)) next if attrs.empty? captured[klass.name] = serialize_attrs(klass, attrs) end captured.empty? ? nil : captured end |
.enabled?(config = Pgbus.configuration) ⇒ Boolean
26 27 28 |
# File 'lib/pgbus/current_attributes.rb', line 26 def enabled?(config = Pgbus.configuration) !config.current_attributes.nil? end |
.normalize(value) ⇒ Object
Config/override value → nil | :auto | [{ name:, only:, except: }]. Raises Pgbus::ConfigurationError for anything else.
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/pgbus/current_attributes.rb', line 64 def normalize(value) case value when nil then nil when :auto then :auto when Array then value.map { |entry| class_spec(entry, {}) } when Hash then value.map { |entry, filters| class_spec(entry, filters) } else raise Pgbus::ConfigurationError, "current_attributes must be nil, :auto, an Array of CurrentAttributes classes/names, " \ "or a Hash of class/name => { only: [...] } | { except: [...] } (got #{value.inspect})" end end |
.persisted_specs(config = Pgbus.configuration, override: nil) ⇒ Object
Normalized [{ name:, only:, except: }] for the config (or override).
78 79 80 81 82 83 84 85 86 |
# File 'lib/pgbus/current_attributes.rb', line 78 def persisted_specs(config = Pgbus.configuration, override: nil) source = override.nil? ? config.current_attributes : normalize(override) return [] if source.nil? || source == false return source unless source == :auto ActiveSupport::CurrentAttributes.descendants.filter_map do |klass| { name: klass.name, only: nil, except: nil } if klass.name end end |
.restore(stored, &block) ⇒ Object
Set every stored class's attributes for the block; previous values come back afterwards (ActiveSupport::CurrentAttributes#set semantics).
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/pgbus/current_attributes.rb', line 50 def restore(stored, &block) return yield if stored.nil? || stored.empty? stored.reduce(block) do |inner, (name, attrs)| klass = resolve_class(name) next inner unless klass values = deserialize_attrs(klass, attrs) -> { klass.set(values) { inner.call } } end.call end |