Class: OpenTrace::MemoryGuard

Inherits:
Object
  • Object
show all
Defined in:
lib/opentrace/memory_guard.rb

Overview

Global memory guard that tracks total buffer usage across all concurrent requests. When the global limit is exceeded, new requests fall back to :minimal capture depth until memory drops.

Also implements adaptive capture depth — monitors queue fill level and auto-downgrades capture when the system is under pressure.

Constant Summary collapse

CAPTURE_LEVELS =
%i[none minimal standard full].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_total_bytes: 52_428_800, pressure_threshold: 0.8) ⇒ MemoryGuard

Returns a new instance of MemoryGuard.



15
16
17
18
19
20
21
# File 'lib/opentrace/memory_guard.rb', line 15

def initialize(max_total_bytes: 52_428_800, pressure_threshold: 0.8)
  @max_total_bytes    = max_total_bytes
  @pressure_threshold = pressure_threshold # 0.0-1.0, fraction of queue capacity
  @current_bytes      = 0
  @mutex              = Mutex.new
  @under_pressure     = false
end

Instance Attribute Details

#max_total_bytesObject (readonly)

Returns the value of attribute max_total_bytes.



13
14
15
# File 'lib/opentrace/memory_guard.rb', line 13

def max_total_bytes
  @max_total_bytes
end

#pressure_thresholdObject (readonly)

Returns the value of attribute pressure_threshold.



13
14
15
# File 'lib/opentrace/memory_guard.rb', line 13

def pressure_threshold
  @pressure_threshold
end

Instance Method Details

#allocate(bytes) ⇒ Object

Called when a request buffer starts accumulating data. Returns true if the allocation is allowed.



25
26
27
28
29
30
31
32
33
34
# File 'lib/opentrace/memory_guard.rb', line 25

def allocate(bytes)
  @mutex.synchronize do
    if @current_bytes + bytes > @max_total_bytes
      false
    else
      @current_bytes += bytes
      true
    end
  end
end

#current_bytesObject

Current total bytes across all concurrent buffers.



44
45
46
# File 'lib/opentrace/memory_guard.rb', line 44

def current_bytes
  @mutex.synchronize { @current_bytes }
end

#effective_level(configured_level) ⇒ Object

Resolve the effective capture level, taking memory and pressure into account. The configured level may be downgraded if the system is under stress.



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/opentrace/memory_guard.rb', line 68

def effective_level(configured_level)
  @mutex.synchronize do
    if @current_bytes >= @max_total_bytes
      :minimal
    elsif @under_pressure
      downgrade(configured_level)
    else
      configured_level
    end
  end
end

#exceeded?Boolean

Whether the global limit has been exceeded.

Returns:

  • (Boolean)


49
50
51
# File 'lib/opentrace/memory_guard.rb', line 49

def exceeded?
  @mutex.synchronize { @current_bytes >= @max_total_bytes }
end

#release(bytes) ⇒ Object

Called when a request buffer is released (request ends).



37
38
39
40
41
# File 'lib/opentrace/memory_guard.rb', line 37

def release(bytes)
  @mutex.synchronize do
    @current_bytes = [0, @current_bytes - bytes].max
  end
end

#reset!Object

Reset state (for testing).



81
82
83
84
85
86
# File 'lib/opentrace/memory_guard.rb', line 81

def reset!
  @mutex.synchronize do
    @current_bytes  = 0
    @under_pressure = false
  end
end

#statsObject



88
89
90
91
92
93
94
95
96
97
# File 'lib/opentrace/memory_guard.rb', line 88

def stats
  @mutex.synchronize do
    {
      current_bytes: @current_bytes,
      max_total_bytes: @max_total_bytes,
      usage_pct: @max_total_bytes > 0 ? ((@current_bytes.to_f / @max_total_bytes) * 100).round(1) : 0.0,
      under_pressure: @under_pressure
    }
  end
end

#under_pressure?Boolean

Whether the system is currently under pressure.

Returns:

  • (Boolean)


62
63
64
# File 'lib/opentrace/memory_guard.rb', line 62

def under_pressure?
  @mutex.synchronize { @under_pressure }
end

#update_pressure(queue_fill_ratio) ⇒ Object

Update pressure state based on queue fill ratio (0.0-1.0). Called periodically by the background thread.



55
56
57
58
59
# File 'lib/opentrace/memory_guard.rb', line 55

def update_pressure(queue_fill_ratio)
  @mutex.synchronize do
    @under_pressure = queue_fill_ratio >= @pressure_threshold
  end
end