Class: Smith::Tool::BoundedCompletionGuard

Inherits:
Object
  • Object
show all
Defined in:
lib/smith/tool/bounded_completion_guard.rb

Instance Method Summary collapse

Constructor Details

#initializeBoundedCompletionGuard

Returns a new instance of BoundedCompletionGuard.



6
7
8
9
10
11
12
13
# File 'lib/smith/tool/bounded_completion_guard.rb', line 6

def initialize
  @state = nil
  @state_mutex = Mutex.new
  @owner = nil
  @depth = 0
  @owner_mutex = Mutex.new
  @admissions = nil
end

Instance Method Details

#admission_for(tool_call) ⇒ Object



54
55
56
# File 'lib/smith/tool/bounded_completion_guard.rb', line 54

def admission_for(tool_call)
  @admissions&.fetch(tool_call, nil)
end

#admissions_for(tool_calls) ⇒ Object



58
59
60
61
62
63
# File 'lib/smith/tool/bounded_completion_guard.rb', line 58

def admissions_for(tool_calls)
  tool_calls.each_with_object({}.compare_by_identity) do |tool_call, admissions|
    admission = admission_for(tool_call)
    admissions[tool_call] = admission if admission
  end.freeze
end

#around_completion(owner, reentrant:, &block) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/smith/tool/bounded_completion_guard.rb', line 15

def around_completion(owner, reentrant:, &block)
  Thread.handle_interrupt(Object => :never) do
    enter(owner, reentrant:)
    begin
      Thread.handle_interrupt(Object => :immediate, &block)
    ensure
      leave(owner)
    end
  end
end

#state_for(allowance) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/smith/tool/bounded_completion_guard.rb', line 26

def state_for(allowance)
  @state_mutex.synchronize do
    return @state if @state&.allowance.equal?(allowance)

    @state = BoundedCompletionState.new(allowance: allowance)
  end
end

#with_admitted_calls(tool_calls, tools:, allowance:, ledger:, &block) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/smith/tool/bounded_completion_guard.rb', line 34

def with_admitted_calls(tool_calls, tools:, allowance:, ledger:, &block)
  Thread.handle_interrupt(Object => :never) do
    reservation = allowance.reserve_batch(tool_calls.each_value.map(&:name), ledger:)
    return false unless reservation

    previous = @admissions
    @admissions = build_admissions(tool_calls, tools, reservation)
    begin
      Thread.handle_interrupt(Object => :immediate, &block)
    ensure
      begin
        reservation.settle!
      ensure
        @admissions = previous
      end
    end
    true
  end
end