class RubyLLM::Browser::Rails::Reaper

Durable cleanup and reconciliation sweep for the Rails adapter.

The reaper is the safety net for operations whose worker died, whose start or end outcome is unknown, or that exceeded their wall-clock budget. It never invents success: it asks the backend to reconcile, attempts a real session close, and leaves ‘unknown` / `cleanup_pending` visible (with the reservation held) until closure or provider expiry is confirmed.

RubyLLM::Browser::Rails::Reaper.new(backend: qualified_backend).sweep

Closing or re-marking an operation bumps its fence, so a surviving worker that resumes after the sweep is refused as stale.

Public Class Methods

new(backend:, store: nil, clock: nil, logger: nil, ttl_seconds: nil) click to toggle source

@param backend [RubyLLM::Browser::Backend] used to reconcile and close sessions @param store [RubyLLM::Browser::OperationStore] defaults to the module store @param ttl_seconds [Numeric, nil] optional idle TTL in addition to the budget

# File lib/ruby_llm/browser/rails/reaper.rb, line 22
def initialize(backend:, store: nil, clock: nil, logger: nil, ttl_seconds: nil)
  @backend = backend
  @store = store || RubyLLM::Browser::Rails.operation_store
  @clock = clock || RubyLLM::Browser::Rails.clock
  @logger = logger || RubyLLM::Browser.logger
  @ttl_seconds = ttl_seconds
  if ttl_seconds && !(ttl_seconds.is_a?(Numeric) && ttl_seconds.finite? && ttl_seconds.positive?)
    raise InvalidInput, "reaper TTL must be a positive finite number"
  end
end

Public Instance Methods

sweep(now: nil) click to toggle source

Sweeps every open operation once.

@return [Hash] counts keyed by outcome (‘:checked`, `:closed`, `:cleanup_pending`,

`:unknown`, `:kept`) plus `:at`
# File lib/ruby_llm/browser/rails/reaper.rb, line 37
def sweep(now: nil)
  time = now || @clock.call
  summary = Hash.new(0)
  @store.open_operations.each do |operation|
    summary[:checked] += 1
    summary[reap(operation, time)] += 1
  end
  summary[:at] = time
  summary
end