Class: Parse::Agent::MCPRackApp::CancellationRegistry Private
- Inherits:
-
Object
- Object
- Parse::Agent::MCPRackApp::CancellationRegistry
- Defined in:
- lib/parse/agent/mcp_rack_app.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Per-app store of in-flight cancellable requests. Lookups for cancellation are keyed by ‘[correlation_id, request_id]`, but every #register returns an opaque entry-id token that uniquely identifies the registration. #deregister requires that entry-id and removes the matching token only when it still owns the slot — so a second registration under the same `(correlation_id, request_id)` key cannot cause the first registration’s ‘on_close` to evict the wrong token.
SSEBody registers an entry before spawning its dispatcher_thread and deregisters via the MCPRackApp-supplied on_close hook. A ‘notifications/cancelled` POST calls #cancel to trip the matching CancellationToken.
Identity binding: cancellation requires the cancelling request’s ‘X-MCP-Session-Id` (sanitized into `agent.correlation_id`) to match the original request’s. This prevents an attacker who guesses sequential JSON-RPC request ids from cancelling other clients’ in-flight requests. A registration with a nil correlation_id is dropped silently (cancellation is disabled for the request).
Scope: per MCPRackApp instance. Cancellation does NOT span multiple mount points within a process, nor multiple processes in a clustered deployment.
Instance Method Summary collapse
-
#cancel(correlation_id, request_id, reason: :notifications_cancelled) ⇒ Boolean
private
Trip the matching token.
-
#deregister(correlation_id, request_id, entry_id) ⇒ Boolean
private
Release a previously-registered entry.
-
#initialize ⇒ CancellationRegistry
constructor
private
A new instance of CancellationRegistry.
-
#register(correlation_id, request_id, token) ⇒ String?
private
Register a cancellation token for the given session and request id pair.
-
#size ⇒ Integer
private
Number of currently-registered tokens.
Constructor Details
#initialize ⇒ CancellationRegistry
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of CancellationRegistry.
961 962 963 964 |
# File 'lib/parse/agent/mcp_rack_app.rb', line 961 def initialize @entries = {} @mutex = Mutex.new end |
Instance Method Details
#cancel(correlation_id, request_id, reason: :notifications_cancelled) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Trip the matching token. Silent no-op when the entry is missing — by design, to avoid a probe oracle.
1016 1017 1018 1019 1020 1021 1022 |
# File 'lib/parse/agent/mcp_rack_app.rb', line 1016 def cancel(correlation_id, request_id, reason: :notifications_cancelled) return false if correlation_id.nil? || correlation_id.to_s.empty? entry = @mutex.synchronize { @entries[[correlation_id, request_id]] } return false unless entry entry[1].cancel!(reason: reason) true end |
#deregister(correlation_id, request_id, entry_id) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Release a previously-registered entry. Removes the slot only when the current owner matches the passed entry-id, so a stale on_close from a request whose slot was overwritten by a sibling registration cannot evict the sibling’s token. Idempotent.
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 |
# File 'lib/parse/agent/mcp_rack_app.rb', line 998 def deregister(correlation_id, request_id, entry_id) return false if correlation_id.nil? || correlation_id.to_s.empty? return false if entry_id.nil? @mutex.synchronize do current = @entries[[correlation_id, request_id]] if current && current[0] == entry_id @entries.delete([correlation_id, request_id]) true else false end end end |
#register(correlation_id, request_id, token) ⇒ String?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Register a cancellation token for the given session and request id pair. Returns an opaque entry-id that the caller must pass to #deregister to release the slot. If multiple registrations land on the same key (legitimate id-reuse by the same session, or a request retry), only the latest registration is reachable for #cancel; older entries can still be safely released via their entry-id even though they no longer “own” the slot.
982 983 984 985 986 987 988 989 |
# File 'lib/parse/agent/mcp_rack_app.rb', line 982 def register(correlation_id, request_id, token) return nil if correlation_id.nil? || correlation_id.to_s.empty? entry_id = SecureRandom.uuid @mutex.synchronize do @entries[[correlation_id, request_id]] = [entry_id, token] end entry_id end |
#size ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns number of currently-registered tokens. Used by tests and operator dashboards.
1026 1027 1028 |
# File 'lib/parse/agent/mcp_rack_app.rb', line 1026 def size @mutex.synchronize { @entries.size } end |