Class: FiberAudit::Runtime::Recorder

Inherits:
Object
  • Object
show all
Defined in:
lib/fiber_audit/runtime/recorder.rb

Overview

Thread-safe coordinator for one bounded append-only runtime session. rubocop:disable Metrics/ClassLength

Constant Summary collapse

RESULTS =
%i[
  emitted sampled_out rate_limited session_event_limited session_byte_limited
  oversize internal_error inactive
].freeze
MAX_COUNTER =
Limits::MAX_COUNTER
OUTCOME_COUNTERS =
6

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(session:, writer:, clock: Clock.new, random: Sampler::RANDOM_SOURCE) ⇒ Recorder

Returns a new instance of Recorder.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/fiber_audit/runtime/recorder.rb', line 28

def initialize(session:, writer:, clock: Clock.new, random: Sampler::RANDOM_SOURCE)
  validate_dependencies!(session, writer, clock, random)
  @session = session
  @writer = writer
  @clock = clock
  @mutex = Mutex.new
  @state = :starting
  @sequence = 1
  @in_flight = 0
  @start_written = false
  @summary = nil
  @limits = Limits.new(policy: session.policy, started_monotonic_ns: session.started_monotonic_ns)
  @sampler = Sampler.new(policy: session.policy, random: random)
  @end_reserve_bytes = end_reserve_bytes
  start_session!
rescue StandardError => e
  startup_failure!(e)
end

Instance Attribute Details

#sessionObject (readonly)

Returns the value of attribute session.



22
23
24
# File 'lib/fiber_audit/runtime/recorder.rb', line 22

def session
  @session
end

#writerObject (readonly)

Returns the value of attribute writer.



22
23
24
# File 'lib/fiber_audit/runtime/recorder.rb', line 22

def writer
  @writer
end

Class Method Details

.startObject



24
25
26
# File 'lib/fiber_audit/runtime/recorder.rb', line 24

def self.start(...)
  new(...)
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/fiber_audit/runtime/recorder.rb', line 88

def active?
  state?(:active)
end

#close(status: :completed) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/fiber_audit/runtime/recorder.rb', line 67

def close(status: :completed)
  requested_status = normalize_status(status)
  @mutex.synchronize do
    return @summary if @summary

    @state = :closing
    @limits.internal_error!(count: @in_flight) if @in_flight.positive?
    ended_at, ended_monotonic_ns, clock_error = closing_times
    errors = [clock_error].compact
    summary = build_summary(requested_status, ended_at, ended_monotonic_ns)
    errors.concat(write_end_record(summary))
    errors.concat(close_writer)
    summary = build_summary(requested_status, ended_at, ended_monotonic_ns) unless errors.empty?
    @summary = summary
    @state = :closed
    raise errors.first if errors.any? && !session.policy.fail_open?

    @summary
  end
end

#closed?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/fiber_audit/runtime/recorder.rb', line 96

def closed?
  state?(:closed)
end

#disabled?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/fiber_audit/runtime/recorder.rb', line 92

def disabled?
  state?(:disabled)
end

#internal_error!Object

Accounts an instrumentation failure without retaining exception data.



58
59
60
61
62
63
64
65
# File 'lib/fiber_audit/runtime/recorder.rb', line 58

def internal_error!
  @mutex.synchronize do
    return false if @state == :closed

    @limits.internal_error!
    true
  end
end

#record(&factory) ⇒ Object



47
48
49
# File 'lib/fiber_audit/runtime/recorder.rb', line 47

def record(&factory)
  record_observation(sample: true, factory: factory)
end

#record_control(&factory) ⇒ Object

Control evidence is never sampled, but still consumes every configured rate, count, record-size, and session-size budget.



53
54
55
# File 'lib/fiber_audit/runtime/recorder.rb', line 53

def record_control(&factory)
  record_observation(sample: false, factory: factory)
end

#summaryObject



100
101
102
# File 'lib/fiber_audit/runtime/recorder.rb', line 100

def summary
  @mutex.synchronize { @summary }
end