Class: HotCell::Counters

Inherits:
Object
  • Object
show all
Defined in:
lib/hot_cell/counters.rb

Overview

These live in the supervisor, and a forked worker can still report them: a child inherits the supervisor's memory at fork, so the worker answering a metrics request reads a consistent snapshot of counters it never had to be told. This is the one place fork-per-request is a convenience rather than a cost.

Three of these are not derivable on the client side, which is why the control channel exists at all. queue_high_water is the leading saturation signal and no single caller sees it. killed_by separates a decompression bomb from a slow afternoon in aggregate. cancelled counts callers that gave up before the cell answered, which by definition appears on no response.

cancelled is a floor rather than a total, and the reason is where each answer is written from. The supervisor writes refusals, kills and deadline breaches, so it sees the broken pipe and counts it. A successful conversion is written by the worker, which exits without telling anyone — so a caller that hangs up during one is not counted. Read it as "at least this many", and read a rise as real.

Instance Method Summary collapse

Constructor Details

#initializeCounters

Returns a new instance of Counters.



19
20
21
22
23
24
25
# File 'lib/hot_cell/counters.rb', line 19

def initialize
  @started_at = Clock.now
  @requests = Hash.new(0)
  @killed_by = Hash.new(0)
  @cancelled = 0
  @queue_high_water = 0
end

Instance Method Details

#cancelled!Object



36
37
38
# File 'lib/hot_cell/counters.rb', line 36

def cancelled!
  @cancelled += 1
end

#observe_queue(depth) ⇒ Object



40
41
42
# File 'lib/hot_cell/counters.rb', line 40

def observe_queue(depth)
  @queue_high_water = depth if depth > @queue_high_water
end

#record(code) ⇒ Object



27
28
29
30
# File 'lib/hot_cell/counters.rb', line 27

def record(code)
  @requests[:total] += 1
  @requests[(code || :ok).to_sym] += 1
end

#record_kill(cause) ⇒ Object



32
33
34
# File 'lib/hot_cell/counters.rb', line 32

def record_kill(cause)
  @killed_by[cause.to_sym] += 1
end

#to_h(running: 0, queued: 0) ⇒ Object



44
45
46
47
48
# File 'lib/hot_cell/counters.rb', line 44

def to_h(running: 0, queued: 0)
  { uptime_s: (Clock.now - @started_at).round, running: running, queued: queued,
    queue_high_water: @queue_high_water, requests: @requests, killed_by: @killed_by,
    cancelled: @cancelled }
end