Class: OrangeTap::Session
- Inherits:
-
Object
- Object
- OrangeTap::Session
- Defined in:
- lib/orange_tap/session.rb
Overview
Controls a single recording session's lifecycle. Each #open call creates a dedicated Queue and Worker Thread; there is no session_id, because the Queue instance itself is what scopes events to this session. This also makes concurrent sessions (multiple Session instances open at once) work without any cross-session bookkeeping: each has its own Queue, Thread, and TracePoint set.
Instance Method Summary collapse
-
#initialize(registry: OrangeTap.default_registry, config: OrangeTap.config) ⇒ Session
constructor
A new instance of Session.
- #open(session_name = nil) ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(registry: OrangeTap.default_registry, config: OrangeTap.config) ⇒ Session
Returns a new instance of Session.
13 14 15 16 17 18 19 |
# File 'lib/orange_tap/session.rb', line 13 def initialize(registry: OrangeTap.default_registry, config: OrangeTap.config) @registry = registry @config = config @queue = nil @worker_thread = nil @tracepoint_targets = nil end |
Instance Method Details
#open(session_name = nil) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/orange_tap/session.rb', line 21 def open(session_name = nil) raise AlreadyOpenError if @queue # Anchor monotonic time to wall-clock time once, at session start, so # OtelConverter can later translate CLOCK_MONOTONIC-based timestamps # (cheap, used inside the hot hook) into absolute OTLP unix ns. start_mono_ns = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) start_unix_ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) trace_id = SecureRandom.hex(16) @queue = Thread::Queue.new # Start the worker before building the TracePoints so its Thread can be # captured by the global app hook (which must skip the worker's own # calls). Tracing is not active yet, so nothing the worker does now is # recorded. ctx = Worker::Context.new( queue: @queue, config: @config, trace_id: trace_id, start_mono_ns: start_mono_ns, start_unix_ns: start_unix_ns, session_name: session_name ) @worker_thread = Thread.new(ctx) { |worker_ctx| Worker.new(worker_ctx).run } # Entries are [tracepoint, iseq]; a nil iseq marks a global (targetless) # hook, which is enabled without a target: below. @tracepoint_targets = build_tracepoint_targets @tracepoint_targets.each { |tp, iseq| iseq ? tp.enable(target: iseq) : tp.enable } self end |
#stop ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/orange_tap/session.rb', line 52 def stop raise NotOpenError unless @queue # Disable hooks before closing the queue / waiting on the worker, so # that even if the worker raises, tracing has already stopped and # cannot leak into whatever runs next. @tracepoint_targets.each { |tp, _iseq| tp.disable } @queue.close path = @worker_thread.value @queue = nil @tracepoint_targets = nil @worker_thread = nil path end |