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
@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
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