Class: RubyLLM::MCP::Handlers::AsyncResponse
- Inherits:
-
Object
- Object
- RubyLLM::MCP::Handlers::AsyncResponse
- Defined in:
- lib/ruby_llm/mcp/handlers/async_response.rb
Overview
Represents an async response for deferred completion
Constant Summary collapse
- VALID_STATES =
%i[pending completed rejected cancelled timed_out].freeze
Instance Attribute Summary collapse
-
#elicitation_id ⇒ Object
readonly
Returns the value of attribute elicitation_id.
Instance Method Summary collapse
-
#cancel(reason) ⇒ Object
Cancel the async operation.
-
#cancelled? ⇒ Boolean
Check if operation is cancelled.
-
#complete(data) ⇒ Object
Complete the async operation with data.
-
#completed? ⇒ Boolean
Check if operation is completed.
- #error ⇒ Object
-
#finished? ⇒ Boolean
Check if operation is finished (any terminal state).
-
#initialize(elicitation_id:, timeout: nil, timeout_handler: nil) ⇒ AsyncResponse
constructor
Initialize async response.
-
#on_complete(&callback) ⇒ Object
Register a callback for when operation completes/fails.
-
#pending? ⇒ Boolean
Check if operation is pending.
-
#reject(reason) ⇒ Object
Reject the async operation.
-
#rejected? ⇒ Boolean
Check if operation is rejected.
- #result ⇒ Object
- #state ⇒ Object
-
#timed_out? ⇒ Boolean
Check if operation timed out.
-
#timeout! ⇒ Object
Mark as timed out.
Constructor Details
#initialize(elicitation_id:, timeout: nil, timeout_handler: nil) ⇒ AsyncResponse
Initialize async response
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 16 def initialize(elicitation_id:, timeout: nil, timeout_handler: nil) @elicitation_id = elicitation_id @state = :pending @result = nil @error = nil @mutex = Mutex.new @timeout = timeout @timeout_handler = timeout_handler @completion_callbacks = [] @created_at = Time.now RubyLLM::MCP.logger.debug("AsyncResponse created for #{@elicitation_id} with timeout: #{@timeout || 'none'}") schedule_timeout if @timeout end |
Instance Attribute Details
#elicitation_id ⇒ Object (readonly)
Returns the value of attribute elicitation_id.
8 9 10 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 8 def elicitation_id @elicitation_id end |
Instance Method Details
#cancel(reason) ⇒ Object
Cancel the async operation
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 65 def cancel(reason) callbacks_to_execute = nil transitioned = transition_state(:cancelled) do @error = reason callbacks_to_execute = @completion_callbacks.dup end execute_callbacks_safely(callbacks_to_execute, :cancelled, reason) if transitioned && callbacks_to_execute end |
#cancelled? ⇒ Boolean
Check if operation is cancelled
112 113 114 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 112 def cancelled? @mutex.synchronize { @state == :cancelled } end |
#complete(data) ⇒ Object
Complete the async operation with data
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 33 def complete(data) callbacks_to_execute = nil transitioned = transition_state(:completed) do @result = data callbacks_to_execute = @completion_callbacks.dup end if transitioned duration = Time.now - @created_at RubyLLM::MCP.logger.debug("AsyncResponse #{@elicitation_id} completed after #{duration.round(3)}s") end # Execute callbacks outside mutex to avoid deadlocks execute_callbacks_safely(callbacks_to_execute, :completed, data) if transitioned && callbacks_to_execute end |
#completed? ⇒ Boolean
Check if operation is completed
102 103 104 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 102 def completed? @mutex.synchronize { @state == :completed } end |
#error ⇒ Object
134 135 136 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 134 def error @mutex.synchronize { @error } end |
#finished? ⇒ Boolean
Check if operation is finished (any terminal state)
122 123 124 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 122 def finished? !pending? end |
#on_complete(&callback) ⇒ Object
Register a callback for when operation completes/fails
90 91 92 93 94 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 90 def on_complete(&callback) @mutex.synchronize do @completion_callbacks << callback end end |
#pending? ⇒ Boolean
Check if operation is pending
97 98 99 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 97 def pending? @mutex.synchronize { @state == :pending } end |
#reject(reason) ⇒ Object
Reject the async operation
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 52 def reject(reason) callbacks_to_execute = nil transitioned = transition_state(:rejected) do @error = reason callbacks_to_execute = @completion_callbacks.dup end execute_callbacks_safely(callbacks_to_execute, :rejected, reason) if transitioned && callbacks_to_execute end |
#rejected? ⇒ Boolean
Check if operation is rejected
107 108 109 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 107 def rejected? @mutex.synchronize { @state == :rejected } end |
#result ⇒ Object
130 131 132 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 130 def result @mutex.synchronize { @result } end |
#state ⇒ Object
126 127 128 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 126 def state @mutex.synchronize { @state } end |
#timed_out? ⇒ Boolean
Check if operation timed out
117 118 119 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 117 def timed_out? @mutex.synchronize { @state == :timed_out } end |
#timeout! ⇒ Object
Mark as timed out
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ruby_llm/mcp/handlers/async_response.rb', line 77 def timeout! callbacks_to_execute = nil transitioned = transition_state(:timed_out) do @error = "Operation timed out" callbacks_to_execute = @completion_callbacks.dup end execute_callbacks_safely(callbacks_to_execute, :timed_out, @error) if transitioned && callbacks_to_execute end |