Skip to content

Conversation

@y0geshdev
Copy link

Motivation and Context

How Has This Been Tested?

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Refactored `EventStoreCleanupService` to use a new `IEventStoreCleaner` interface, separating cleanup responsibilities from the `IEventStore` interface.

- Introduced `IEventStoreCleaner` with a `CleanEventStore` method.
- Updated `InMemoryEventStore` to implement `IEventStoreCleaner`.
- Removed `CleanupEventStore` from `IEventStore`.
- Registered `InMemoryEventStore` as both `IEventStore` and `IEventStoreCleaner` in DI.
- Updated logging messages to reflect the new terminology.

This change improves modularity and adheres to the Single Responsibility Principle.
Copy link
Contributor

@halter73 halter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing a PR to add resumability support!!

We have an issue tracking this at #510 and plan on adding client-side support for this too. I think resumability will likely get a lot more use in the future, especially if modelcontextprotocol/modelcontextprotocol#1699 is adopted which allows the server to ask the client to poll.

I know other SDK's have some support for this already, and so far, all of them have left the InMemoryEventStore as a sample which is certainly the easiest thing to do from the SDK's perpective, but I think it'd be nice for application developers if we were able to provide something that is production-ready shipped as part of the SDK. Perhaps something based on MemoryCache. I'm curious what @stephentoub thoughts are on that.

I think I'm going to take over this issue, but I do like your overall design. I'll be sure to consider your design and follow it where it makes sense while adding test coverage.

I'm curious why you split string? GetEventId(string streamId, JsonRpcMessage message) and StoreEvent(string streamId, SseItem<JsonRpcMessage?> messageItem). Why not just ValueTask<string> StoreEvent(string streamId, JsonRpcMessage messagge)? I also wonder if there's any way we could bind the eventId to the current user ID, so that even if the eventId was stolen by an otherwise unauthenticated attacker, they would be unable to exfiltrate messages via the resumability feature.

@stephentoub
Copy link
Contributor

Perhaps something based on MemoryCache. I'm curious what @stephentoub thoughts are on that.

If there's a clean way we could leverage existing interfaces / concepts, like utilizing IDistributedCache, that'd be my preference, as then we already have a plethora of implementations available in the ecosystem (including in-memory) and we wouldn't need the concrete implementations in the SDK.

@y0geshdev
Copy link
Author

I'm curious why you split string? GetEventId(string streamId, JsonRpcMessage message) and StoreEvent(string streamId, SseItem<JsonRpcMessage?> messageItem). Why not just ValueTask StoreEvent(string streamId, JsonRpcMessage messagge)?

@halter73 That's a good point. The reason I split those 2 method is because I am only storing selective events (messages that are of type JsonRpcRequest or JsonRpcResponse for which client request is pending) but I wanted to add eventId for all the server sent events, even if they are not store in event store, so that client will see uniform events structure.

And given the way current code changes are filtering which events to store in EventStore, I would either need to have those 2 separate methods or need to pass the pending client request Id to event store (I didn't wanted to do that).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants