Class: Trailblazer::Developer::Trace::Snapshot
- Inherits:
-
Struct
- Object
- Struct
- Trailblazer::Developer::Trace::Snapshot
- Defined in:
- lib/trailblazer/developer/trace/snapshot.rb,
lib/trailblazer/developer/trace/snapshot/value.rb,
lib/trailblazer/developer/trace/snapshot/versions.rb
Overview
WARNING: the interfaces here are subject to change, we’re still experimenting
with the architecture of tracing, and a healthy balance of performance/memory
and clean design.
A Snapshot comprises of data captured before of after a “step”. This usually includes a ctx snapshot, variable versions and a returned signal for after-step snapshots.
Note that Before and After are generic concepts know to Trace::Present and Debugger.
Snapshot::After{
signal: <End.Success>
ctx_snapshot: Snapshot::Ctx{
variable_versions: [:current_user, 0], [:model, 0]
}
}
Defined Under Namespace
Constant Summary collapse
- Before =
Class.new(Snapshot)
- After =
Class.new(Snapshot)
Instance Attribute Summary collapse
-
#activity ⇒ Object
Returns the value of attribute activity.
-
#data ⇒ Object
Returns the value of attribute data.
-
#task ⇒ Object
Returns the value of attribute task.
Class Method Summary collapse
-
.after_snapshooter(wrap_ctx, _) ⇒ Object
Serialize all ctx variables at the very end of taskWrap, after Out().
-
.before_snapshooter(wrap_ctx, ctx, flow_options), _) ⇒ Object
Serialize all ctx variables before call_task.
-
.call(ctx_snapshooter, wrap_config, ctx, flow_options), circuit_options) ⇒ Object
This is called from capture_args and capture_return in the taskWrap.
-
.snapshot_ctx_for(snapshot, variable_versions) ⇒ Object
Snapshot::Ctx keeps an inspected version of each ctx variable.
- .snapshot_for(ctx, value_snapshooter:, stack:) ⇒ Object
Instance Attribute Details
#activity ⇒ Object
Returns the value of attribute activity
18 19 20 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 18 def activity @activity end |
#data ⇒ Object
Returns the value of attribute data
18 19 20 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 18 def data @data end |
#task ⇒ Object
Returns the value of attribute task
18 19 20 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 18 def task @task end |
Class Method Details
.after_snapshooter(wrap_ctx, _) ⇒ Object
Serialize all ctx variables at the very end of taskWrap, after Out().
49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 49 def self.after_snapshooter(wrap_ctx, _) snapshot_before = wrap_ctx[:snapshot_before] returned_ctx, = wrap_ctx[:return_args] changeset, new_versions = snapshot_for(returned_ctx, **) data = { ctx_variable_changeset: changeset, signal: wrap_ctx[:return_signal], snapshot_before: snapshot_before, # add this so we know who belongs together. } return data, new_versions end |
.before_snapshooter(wrap_ctx, ctx, flow_options), _) ⇒ Object
Serialize all ctx variables before call_task. This is run just before call_task, after In().
38 39 40 41 42 43 44 45 46 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 38 def self.before_snapshooter(wrap_ctx, ((ctx, ), _)) changeset, new_versions = snapshot_for(ctx, **) data = { ctx_variable_changeset: changeset, } return data, new_versions end |
.call(ctx_snapshooter, wrap_config, ctx, flow_options), circuit_options) ⇒ Object
This is called from Trailblazer::Developer::Trace.capture_args and Trailblazer::Developer::Trace.capture_return in the taskWrap.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 23 def self.call(ctx_snapshooter, wrap_config, ((ctx, ), )) # DISCUSS: grab the {snapshooter} here from flow_options, instead of in Trace.capture_args? changeset, new_versions = ctx_snapshooter.call(wrap_config, [[ctx, ], ]) snapshot = new( # either Before or After. wrap_config[:task], [:activity], changeset ).freeze return snapshot, new_versions end |
.snapshot_ctx_for(snapshot, variable_versions) ⇒ Object
Snapshot::Ctx keeps an inspected version of each ctx variable. We figure out if a variable has changed by using ‘variable.hash` (works even with deeply nested structures).
Key idea here is to have minimum work at operation-runtime. Specifics like figuring out what has changed can be done when using the debugger.
By keeping “old” versions, we get three benefits.
-
We only need to call inspect once on a traced variable. Especially when variables are complex structures or strings, this dramatically speeds up tracing, from same-ish to factor 5!
-
The content sent to our debugger is much smaller which reduces network load and storage space.
-
Presentation becomes simpler as we “know” what variable has changed.
Possible problems: when variablevariable.hash returns the same key even though the
data has changed.
DISCUSS: speed up by checking mutable, only? DISCUSS: we currently only use this for testing. DISCUSS: this has knowledge about Trailblazer::Developer::Trace::Stack internals.
This is for the “rendering” layer.
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/trailblazer/developer/trace/snapshot/versions.rb', line 28 def self.snapshot_ctx_for(snapshot, variable_versions) variable_versions = variable_versions.instance_variable_get(:@variables) snapshot.data[:ctx_variable_changeset].collect do |name, hash, has_changed| [ name, { value: variable_versions[name][hash], has_changed: !!has_changed, } ] end.to_h end |
.snapshot_for(ctx, value_snapshooter:, stack:) ⇒ Object
64 65 66 67 68 |
# File 'lib/trailblazer/developer/trace/snapshot.rb', line 64 def self.snapshot_for(ctx, value_snapshooter:, stack:, **) variable_versions = stack.variable_versions variable_versions.changeset_for(ctx, value_snapshooter: value_snapshooter) # return {changeset, new_versions} end |