Description
executeToolCall subscribes fire-and-forget (chain.execute(decoratedExchange).subscribe(...) at line 266) then blocks on responseFuture.get(DEFAULT_TIMEOUT_SECONDS, …). On TimeoutException it throws, but the Disposable returned by subscribe() is never captured/cancelled, and doFinally does not cancel the chain. The downstream request keeps running after the tool call has already returned an error to the MCP client.
Location
shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java:266-283
Impact
Timed-out tool calls leak downstream work/connections and may produce side effects (e.g. upstream API calls) after the client has received an error.
Suggested fix
Capture the Disposable, and on TimeoutException call disposable.dispose() before throwing.
Related existing
None — distinct from MCP-01..05 (#6640-#6644, response decorator) and MCP-11 (notifications).
Description
executeToolCallsubscribes fire-and-forget (chain.execute(decoratedExchange).subscribe(...)at line 266) then blocks onresponseFuture.get(DEFAULT_TIMEOUT_SECONDS, …). OnTimeoutExceptionit throws, but theDisposablereturned bysubscribe()is never captured/cancelled, anddoFinallydoes not cancel the chain. The downstream request keeps running after the tool call has already returned an error to the MCP client.Location
shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java:266-283Impact
Timed-out tool calls leak downstream work/connections and may produce side effects (e.g. upstream API calls) after the client has received an error.
Suggested fix
Capture the
Disposable, and onTimeoutExceptioncalldisposable.dispose()before throwing.Related existing
None — distinct from MCP-01..05 (#6640-#6644, response decorator) and MCP-11 (notifications).