Module: Axn::Core::AmbientContext
- Defined in:
- lib/axn/core/ambient_context.rb
Overview
ambient_context is a reserved, always-present parent on every Axn. Its reader returns a Hash
({} by default) that subfields extract from via expects :x, on: :ambient_context. Reads are
declaration-gated (a reader exists only for declared subfields), and the hash is filtered to the
declared ambient keys — along their declared PATHS (PRO-2909), so a deeply nested ambient
subfield resolves its value while the hash still never carries an undeclared sibling or a
process-wide dump of Current state.
Defined Under Namespace
Modules: ClassMethods Classes: AmbientSubfieldTreeCacheEntry
Constant Summary collapse
- PARENT =
:ambient_context
Class Method Summary collapse
-
.default_source ⇒ Object
Default ambient-context source: a live view over every registered
ActiveSupport:: CurrentAttributes. - .included(base) ⇒ Object
Instance Method Summary collapse
-
#ambient_context ⇒ Object
Instance reader used by ContractForSubfields.resolve_parent (public_send(:ambient_context)).
Class Method Details
.default_source ⇒ Object
Default ambient-context source: a live view over every registered ActiveSupport:: CurrentAttributes. Core filters the result down to each Axn's declared ambient keys
(see _filter_to_declared), so returning everything here is safe — undeclared keys are
never readable and never injected.
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/axn/core/ambient_context.rb', line 181 def self.default_source return {} unless defined?(ActiveSupport::CurrentAttributes) ActiveSupport::CurrentAttributes.descendants.each_with_object({}) do |klass, acc| # When two CurrentAttributes classes declare the same attribute, last-descendant-wins # silently (by design per spec — core filters to declared keys downstream, so undeclared # collisions never surface). acc.merge!(klass.instance.attributes) end end |
.included(base) ⇒ Object
22 23 24 |
# File 'lib/axn/core/ambient_context.rb', line 22 def self.included(base) base.extend(ClassMethods) end |
Instance Method Details
#ambient_context ⇒ Object
Instance reader used by ContractForSubfields.resolve_parent (public_send(:ambient_context)).
A failing provider is memoized as an ERROR (not {}) and re-raised on every subsequent read.
This matters because automatic BEFORE-logging can be the FIRST read (a dynamic sensitive:
predicate reading an ambient subfield is evaluated while building the log filter) — and
CallLogger SWALLOWS logging errors. Memoizing {} there would hide the real failure from
inbound validation (which reads ambient_context next) and report a bogus "can't be blank"
instead of the provider's actual exception. Memoizing the error instead means the provider
still runs at most once, but the real error surfaces at the first NON-swallowed read.
201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/axn/core/ambient_context.rb', line 201 def ambient_context raise @__ambient_context_error if defined?(@__ambient_context_error) return @__ambient_context if defined?(@__ambient_context) begin @__ambient_context = _resolve_ambient_context # Memoizes whatever axn absorbs, not just StandardError, or "the provider still runs at most # once" (above) breaks for a provider that blows the stack: it would re-run on every read. rescue StandardError, *Axn::Extensions::SWALLOWABLE_BEYOND_STANDARD_ERROR => e @__ambient_context_error = e raise end end |