feat(McpAsyncServer): Add non-blocking execution for tools and resources

- Execute tool calls, resource reads and prompt handling in a non-blocking
  manner using Schedulers.boundedElastic(). This prevents blocking operations
  from impacting server responsiveness.
- Added integration tests to verify non-blocking behavior with tools that
  make HTTP calls to external services.

Related to #48
This is  a temp patch until #48 is resolved properly.
This commit is contained in:
Christian Tzolov 2025-01-04 17:49:39 +01:00 • committed by Christian Tzolov
commit 580f95526f

View file

@ -374,9 +374,9 @@ public class McpAsyncServer {
return Mono.<Object>error(new McpError("Tool not found: " + callToolRequest.name()));
}
CallToolResult callResponse = toolRegistration.get().call().apply(callToolRequest.arguments());
return Mono.just(callResponse);
return Mono.fromCallable(() -> toolRegistration.get().call().apply(callToolRequest.arguments()))
.map(result -> (Object) result)
.subscribeOn(Schedulers.boundedElastic());
};
}
@ -462,7 +462,9 @@ public class McpAsyncServer {
});
var resourceUri = resourceRequest.uri();
if (this.resources.containsKey(resourceUri)) {
return Mono.just(this.resources.get(resourceUri).readHandler().apply(resourceRequest));
return Mono.fromCallable(() -> this.resources.get(resourceUri).readHandler().apply(resourceRequest))
.map(result -> (Object) result)
.subscribeOn(Schedulers.boundedElastic());
}
return Mono.error(new McpError("Resource not found: " + resourceUri));
};
@ -558,7 +560,10 @@ public class McpAsyncServer {
// Implement prompt retrieval logic here
if (this.prompts.containsKey(promptRequest.name())) {
return Mono.just(this.prompts.get(promptRequest.name()).promptHandler().apply(promptRequest));
return Mono
.fromCallable(() -> this.prompts.get(promptRequest.name()).promptHandler().apply(promptRequest))
.map(result -> (Object) result)
.subscribeOn(Schedulers.boundedElastic());
}
return Mono.error(new McpError("Prompt not found: " + promptRequest.name()));