Stoplight has an internal "telemetry bus": typed event objects get emitted at key moments (a
run finishing, a color change, a lock toggling), and any code that subscribed to that event type
is called with it. Emitter#emit already no-ops cheaply when nobody's subscribed, so there's no
need to check that yourself before calling it.
The original design is PR #721 -- read its
"Motivation" and "What this opens up" sections for the why. All the event types it proposed
already exist as typed value objects (Data.define) under lib/stoplight/domain/telemetry/,
with public RBS signatures under sig/stoplight/telemetry/ -- the shape of every payload is
already decided, so this issue is not about designing anything new. Only RunCompleted is
actually wired up and firing today (PR #742, PR #741). This issue wires up one more:
LockChanged.
lib/stoplight/domain/telemetry/emitter.rb and lib/stoplight/domain/telemetry/run_recorder.rb
show one way this has been done, for RunCompleted -- worth reading for orientation, not a
template to force-fit. run_recorder.rb exists because RunCompleted needed duration measured
and shared across three call sites; that shape may or may not fit this event. Any change under
lib/ needs a matching change under sig/.
What you're wiring up
LockChanged (lib/stoplight/domain/telemetry/lock_changed.rb,
sig/stoplight/telemetry/lock_changed.rbs) fires whenever a human (or a script) manually locks
or unlocks a light -- overriding whatever color the automatic circuit-breaker logic would pick.
Read the sig's own doc comment carefully: this event fires even when the effective color
doesn't change (e.g. locking an already-red light to red again still emits). The point is the
lock action itself being recorded, not a color transition -- don't add a "did the color
actually change" guard, that would be wrong here specifically (unlike the other events in this
set).
Where to make the change
Two separate call paths both need this, since Stoplight has two ways to lock/unlock a light: Domain::Light#lock / #unlock
Payload fields
from_color: / to_color: -- read before/after set_state, or derive from the requested lock
state (State::LOCKED_RED implies Color::RED, etc.) if reading "before" isn't cheap.
from_state: / to_state: -- the light's locked state before and after the call (State::LOCKED_RED,
State::LOCKED_GREEN, State::UNLOCKED).
source: -- remove this field from the event. We decided not to add this information.
References
Stoplight has an internal "telemetry bus": typed event objects get emitted at key moments (a
run finishing, a color change, a lock toggling), and any code that subscribed to that event type
is called with it.
Emitter#emitalready no-ops cheaply when nobody's subscribed, so there's noneed to check that yourself before calling it.
The original design is PR #721 -- read its
"Motivation" and "What this opens up" sections for the why. All the event types it proposed
already exist as typed value objects (
Data.define) underlib/stoplight/domain/telemetry/,with public RBS signatures under
sig/stoplight/telemetry/-- the shape of every payload isalready decided, so this issue is not about designing anything new. Only
RunCompletedisactually wired up and firing today (PR #742, PR #741). This issue wires up one more:
LockChanged.lib/stoplight/domain/telemetry/emitter.rbandlib/stoplight/domain/telemetry/run_recorder.rbshow one way this has been done, for
RunCompleted-- worth reading for orientation, not atemplate to force-fit.
run_recorder.rbexists becauseRunCompletedneeded duration measuredand shared across three call sites; that shape may or may not fit this event. Any change under
lib/needs a matching change undersig/.What you're wiring up
LockChanged(lib/stoplight/domain/telemetry/lock_changed.rb,sig/stoplight/telemetry/lock_changed.rbs) fires whenever a human (or a script) manually locksor unlocks a light -- overriding whatever color the automatic circuit-breaker logic would pick.
Read the sig's own doc comment carefully: this event fires even when the effective color
doesn't change (e.g. locking an already-red light to red again still emits). The point is the
lock action itself being recorded, not a color transition -- don't add a "did the color
actually change" guard, that would be wrong here specifically (unlike the other events in this
set).
Where to make the change
Two separate call paths both need this, since Stoplight has two ways to lock/unlock a light:
Domain::Light#lock/#unlockPayload fields
from_color:/to_color:-- read before/afterset_state, or derive from the requested lockstate(State::LOCKED_REDimpliesColor::RED, etc.) if reading "before" isn't cheap.from_state:/to_state:-- the light's locked state before and after the call (State::LOCKED_RED,State::LOCKED_GREEN,State::UNLOCKED).source:-- remove this field from the event. We decided not to add this information.References
sig/stoplight/telemetry/lock_changed.rbsRunCompletedreference implementation