Class: Insika::TurnTiming
- Inherits:
-
Object
- Object
- Insika::TurnTiming
- Defined in:
- lib/insika/turn_timing.rb
Overview
Opt-in per-turn latency breakdown (locate the
TTFB cost with real-turn data). OFF unless INSIKA_TURN_TIMING is set — when
off the Executor never allocates one and the hot path pays only nil&.mark.
Splits a turn into the three windows that answer "is TTFB local or provider?":
prep_ms — prep_start -> ask: ALL local work before the provider call
(context build, policy, guardrail detectors, chat assembly).
ttft_ms — ask -> first_token: the provider round-trip to the 1st token.
gen_ms — first_token -> done: streaming the rest of the response.
Marks are monotonic; mark is first-write-wins so first_token records the
FIRST content chunk even though it is called on every chunk.
ttft_ms is the PROVIDER's first token, not the first byte the customer can
read: TurnOutput publishes a message once it ends, so the customer-visible
answer lands inside gen_ms. Measuring the provider is the point —'s
baselines (~720 ms, provider-bound) stay comparable across that change.
Class Method Summary collapse
-
.enabled?(env = ENV) ⇒ Boolean
EnvSchema owns "is this flag on?" (1/true/yes/on) — the same predicate that validates the :boolean keys, so a spelling
insika envaccepts is a spelling the reader honours.
Instance Method Summary collapse
-
#initialize(breakdown: true) ⇒ TurnTiming
constructor
breakdown: true (the default) is the flag-on clock: prep/ttft/gen/total.
- #mark(name) ⇒ Object
-
#marked?(name) ⇒ Boolean
Has this mark fired? Used by
SendMessageto prove the channel clock was stamped at 202 acceptance (:inboundbefore the debounce window), and by the pipeline to know a threaded clock already started. -
#to_h ⇒ Object
-> Hash of phase deltas in ms (only the windows whose endpoints both fired; a workflow turn has no ask/first_token, so those are simply absent).
Constructor Details
#initialize(breakdown: true) ⇒ TurnTiming
breakdown: true (the default) is the flag-on clock: prep/ttft/gen/total. false is the channel clock: only :inbound -> :first_balloon, so a channel turn with the flag off still answers H-latência.
38 39 40 41 |
# File 'lib/insika/turn_timing.rb', line 38 def initialize(breakdown: true) @marks = {} @breakdown = breakdown end |
Class Method Details
.enabled?(env = ENV) ⇒ Boolean
EnvSchema owns "is this flag on?" (1/true/yes/on) — the same predicate that
validates the :boolean keys, so a spelling insika env accepts is a spelling
the reader honours.
25 26 27 |
# File 'lib/insika/turn_timing.rb', line 25 def self.enabled?(env = ENV) Insika::EnvSchema.truthy?(Insika::EnvSchema.read("INSIKA_TURN_TIMING", env)) end |
Instance Method Details
#mark(name) ⇒ Object
43 44 45 46 47 |
# File 'lib/insika/turn_timing.rb', line 43 def mark(name) return unless @breakdown || !BREAKDOWN_MARKS.include?(name) @marks[name] ||= Process.clock_gettime(Process::CLOCK_MONOTONIC) end |
#marked?(name) ⇒ Boolean
Has this mark fired? Used by SendMessage to prove the channel clock was
stamped at 202 acceptance (:inbound before the debounce window), and by
the pipeline to know a threaded clock already started.
52 |
# File 'lib/insika/turn_timing.rb', line 52 def marked?(name) = @marks.key?(name) |
#to_h ⇒ Object
-> Hash of phase deltas in ms (only the windows whose endpoints both fired; a workflow turn has no ask/first_token, so those are simply absent). first_balloon_ms is the inbound -> first outbox flush window. A missing number is never a zero — no mark, no key.
58 59 60 61 62 63 64 65 66 |
# File 'lib/insika/turn_timing.rb', line 58 def to_h { prep_ms: delta(:prep_start, :ask), ttft_ms: delta(:ask, :first_token), gen_ms: delta(:first_token, :done), total_ms: delta(:prep_start, :done), first_balloon_ms: delta(:inbound, :first_balloon) }.compact end |