Class: Apartment::PoolReaper
- Inherits:
-
Object
- Object
- Apartment::PoolReaper
- Defined in:
- lib/apartment/pool_reaper.rb
Overview
Evicts idle and excess tenant pools on a background timer. Complementary to ActiveRecord’s ConnectionPool::Reaper which handles intra-pool connection reaping — this handles inter-pool (tenant) eviction.
Instance Method Summary collapse
-
#initialize(pool_manager:, interval:, idle_timeout:, max_total: nil, default_tenant: nil, shard_key_prefix: nil, on_evict: nil) ⇒ PoolReaper
constructor
A new instance of PoolReaper.
-
#run_cycle ⇒ Object
Perform one synchronous eviction pass (idle + LRU).
- #running? ⇒ Boolean
- #start ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(pool_manager:, interval:, idle_timeout:, max_total: nil, default_tenant: nil, shard_key_prefix: nil, on_evict: nil) ⇒ PoolReaper
Returns a new instance of PoolReaper.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/apartment/pool_reaper.rb', line 11 def initialize(pool_manager:, interval:, idle_timeout:, max_total: nil, default_tenant: nil, shard_key_prefix: nil, on_evict: nil) raise(ArgumentError, 'interval must be a positive number') unless interval.is_a?(Numeric) && interval.positive? unless idle_timeout.is_a?(Numeric) && idle_timeout.positive? raise(ArgumentError, 'idle_timeout must be a positive number') end if max_total && (!max_total.is_a?(Integer) || max_total < 1) raise(ArgumentError, 'max_total must be a positive integer or nil') end @pool_manager = pool_manager @interval = interval @idle_timeout = idle_timeout @max_total = max_total @default_tenant = default_tenant @shard_key_prefix = shard_key_prefix @on_evict = on_evict @mutex = Mutex.new @timer = nil end |
Instance Method Details
#run_cycle ⇒ Object
Perform one synchronous eviction pass (idle + LRU). Returns the total number of pools evicted. Called by the background timer and by CLI ‘pool evict`.
52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/apartment/pool_reaper.rb', line 52 def run_cycle count = 0 count += evict_idle count += evict_lru if @max_total count rescue Apartment::ApartmentError => e warn "[Apartment::PoolReaper] #{e.class}: #{e.}" 0 rescue StandardError => e warn "[Apartment::PoolReaper] Unexpected error: #{e.class}: #{e.}" warn e.backtrace&.first(5)&.join("\n") if e.backtrace 0 end |
#running? ⇒ Boolean
45 46 47 |
# File 'lib/apartment/pool_reaper.rb', line 45 def running? @mutex.synchronize { @timer&.running? || false } end |
#start ⇒ Object
32 33 34 35 36 37 38 39 |
# File 'lib/apartment/pool_reaper.rb', line 32 def start @mutex.synchronize do stop_internal @timer = Concurrent::TimerTask.new(execution_interval: @interval) { reap } @timer.execute end self end |
#stop ⇒ Object
41 42 43 |
# File 'lib/apartment/pool_reaper.rb', line 41 def stop @mutex.synchronize { stop_internal } end |