Class: Axn::Core::Executor
- Inherits:
-
Object
- Object
- Axn::Core::Executor
- Defined in:
- lib/axn/core/executor.rb
Overview
rubocop:disable Metrics/ClassLength
Defined Under Namespace
Classes: ConsistencyMismatch, ContractFailure
Instance Method Summary collapse
-
#initialize(action) ⇒ Executor
constructor
A new instance of Executor.
-
#prepare_inbound_for_facets! ⇒ Object
Best-effort inbound preparation for OUT-OF-BAND facet resolution — the async exhaustion/discard report path (Axn::Async::ExceptionReporting), where an action is reconstructed from job args and never executed.
-
#resolve_inbound_facets(sources) ⇒ Object
Input-phase facet resolution for enqueue-time sinks (e.g. Sidekiq job tags), where there is no run to hang completion-time resolution on.
- #run ⇒ Object
Constructor Details
#initialize(action) ⇒ Executor
Returns a new instance of Executor.
211 212 213 214 215 |
# File 'lib/axn/core/executor.rb', line 211 def initialize(action) @action = action @action_class = action.class @context = action.instance_variable_get(:@__context) end |
Instance Method Details
#prepare_inbound_for_facets! ⇒ Object
Best-effort inbound preparation for OUT-OF-BAND facet resolution — the async exhaustion/discard report path (Axn::Async::ExceptionReporting), where an action is reconstructed from job args and never executed. Top-level and subfield coerce/preprocess/default now resolve lazily on the read path (ContractForSubfields.resolve_value), so a facet reading a coerced/defaulted/preprocessed input resolves the value the worker would see with no eager pass — the same lazy behavior model: readers already relied on here. This just clears any pre-pipeline memo so those reads resolve against the settled inputs. Deliberately does NOT validate (a report on already-dead work must never raise) and does NOT run the action. Any failure is swallowed — a partially-prepared instance still yields more facets than a bare one.
244 245 246 247 248 |
# File 'lib/axn/core/executor.rb', line 244 def prepare_inbound_for_facets! Axn::Extensions.best_effort("preparing inbound context for async facet resolution", action: @action) do _clear_pre_pipeline_memos! end end |
#resolve_inbound_facets(sources) ⇒ Object
Input-phase facet resolution for enqueue-time sinks (e.g. Sidekiq job tags), where there is
no run to hang completion-time resolution on. Resolves only from: :inputs facets (via the
memoized resolved_input_* readers) against the RAW enqueued inputs. It deliberately does NOT
run preprocess/defaults: those are user hooks that must execute once, at perform — a dynamic
default:/preprocess: run here would both double-execute (enqueue AND perform) and compute
a value that can differ from the run, so the facet would drift from its own job. Resolving
from raw inputs keeps the facet in lockstep with the serialized payload the worker receives.
from: :result facets are excluded by construction (they can't resolve before the body runs);
a model: field's record still loads lazily (facade.rb) if a resolver reads it. Returns one
resolved map per enabled source (tags, then dimensions), kept SEPARATE so a name declared as
both a tag and a dimension yields two facets rather than one clobbering the other. sources
is a subset of %i[tag dimension]. See PRO-2855.
262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/axn/core/executor.rb', line 262 def resolve_inbound_facets(sources) # Resolve readers in raw mode (ContractForSubfields.resolve_value): a facet reading an input sees the # raw serialized value, not the coerced/preprocessed/defaulted run-time value, so it stays in lockstep # with the payload the worker receives and a dynamic hook is not run at enqueue. @action.instance_variable_set(:@__resolve_raw_reads, true) maps = [] maps << if sources.include?(:tag) maps << resolved_input_dimensions if sources.include?(:dimension) maps ensure @action.remove_instance_variable(:@__resolve_raw_reads) if @action.instance_variable_defined?(:@__resolve_raw_reads) end |
#run ⇒ Object
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/axn/core/executor.rb', line 217 def run Core::NestingTracking.tracking(@action) do with_tracing do with_logging do with_timing do with_exception_handling do with_contract do with_hooks do @action.call end end end end end end end end |