graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Support subscribing to multiple topics on ITopicEventReceiver

Open danbopes opened this issue 3 years ago • 0 comments

Is your feature request related to a problem?

There are times where a subscription may want to subscribe to multiple topics. For instance:

var userId = contextAccessor.HttpContext.User.GetUserId();
return receiver.SubscribeMultipleAsync<string, NotificationInfo>($"user_notifications_${userId}", "global_notifications");

In this case, I may write to a topic of a global notification, but also write to a specific user notification topic. It doesn't make sense to require the client to subscribe twice, and it's returning the same data. Right now, there is no easy way to implement this. See #2914

The solution you'd like

Add a method to ITopicEventReceiver: .SubscribeMultipleAsync(). There are many use cases where subscribing to multiple topics, without clunky workarounds.

My solution required another class:

private class MultipleStreams<TMessage> : ISourceStream<TMessage>
        {
            private readonly List<ISourceStream<TMessage>> _sources;

            public MultipleStreams(IEnumerable<ISourceStream<TMessage>> streams)
            {
                _sources = streams.ToList();
            }

            public async ValueTask DisposeAsync()
            {
                foreach (var source in _sources)
                    await source.DisposeAsync();
            }

            public IAsyncEnumerable<TMessage> ReadEventsAsync() => _sources.Select(s => s.ReadEventsAsync()).ToArray().Merge();

            async IAsyncEnumerable<object> ISourceStream.ReadEventsAsync() => _sources.Select(s => ((ISourceStream)s).ReadEventsAsync()).ToArray().Merge();
        }

Also .Merge() is ugly in AsyncEnumerableEx library. I had to copy one implementation out, which required a ton of extra code bloat. I'd like to see a nice way implemented directly in hot chocolate.

Product

Hot Chocolate

danbopes avatar Jun 23 '22 18:06 danbopes