Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a "SubscribeAsync()" method to the IRealtimeChannel interface #1287

Open
danr-stadion opened this issue Jun 24, 2024 · 4 comments
Open
Labels
enhancement New feature or improved functionality.

Comments

@danr-stadion
Copy link

danr-stadion commented Jun 24, 2024

Hi,

Would it be possible to add a SubscribeAsync() method to the IRealtimeChannel interface? It's currently impossible to make a call to async code in the message handler.

Want to be able to do something like this:

var ablyChannel = ablyRealtime.Channels.Get("channelName");

ablyChannel.SubscribeAsync(async message => { await myObject.MyAsyncMethod(message); });'

The Subscribe method only accepts Action<Message> so you can't pass in a delegate which can be awaited.

Thanks,
Dan.

┆Issue is synchronized with this Jira Task by Unito

@ttypic
Copy link

ttypic commented Jun 25, 2024

Hi @danr-stadion,

Thank you for reporting this issue. Implementing this feature is not straightforward, and we are currently discussing the implementation details internally, as well as deliberating whether we should proceed with it. Additionally, we aim to maintain a consistent public API across all SDKs, necessitating careful consideration of implementation details for other languages as well. In the meantime, you can address this use case by doing something like the following:

var subject = new SequentialSimpleAsyncSubject<Message>();
await subject.Synchronize().SubscribeAsync(async message =>
{
    Console.WriteLine($"DoSomeWorkAsync BEGIN for '{message.Id}'");
    await Task.Delay(5000);
    Console.WriteLine($"DoSomeWorkAsync END for '{message.Id}'");
});
channel.Subscribe(message => subject.OnNextAsync(message));

If you have any difficulties in implementing the workaround, please do not hesitate to reach out to us. We are more than willing to provide assistance.

@ttypic ttypic added the enhancement New feature or improved functionality. label Jun 25, 2024
@danr-stadion
Copy link
Author

Hi @ttypic ,

I tried to implement your workaround but it looks like it depends on an "alpha" Nuget package: https://www.nuget.org/packages/System.Reactive.Async

Unfortunately I'm not comfortable using alpha code in production, so I will just stick with my workaround using task factories.

Thanks,
Dan.

@marto83
Copy link
Contributor

marto83 commented Jun 26, 2024

@danr-stadion, initially, we didn't add an async version to discourage people from doing a lot of extra work in the subscribe actions as the next one can't be called until the current one has finished to ensure the correct order of messages.

I know there are workarounds, but probably the best option is to use something like a blocking queue or the Channel APIs in .net. Ably uses the Channel<T> API to process messages internally, and it works really well.

If you are using it as part of asp.net you can spin up a BackgroundService to process the messages and can queue them in the subscribe action.
I found this guide that might help you get started https://medium.com/@niteshsinghal85/using-channels-for-asynchronous-queuing-in-c-ed96c51d4576 and maybe @ttypic might even do an example 😉

@danr-stadion
Copy link
Author

Thanks @marto83, this looks quite straightforward, we're already using background workers in the application anyway.

@ttypic we can probably close this issue now.

Cheers,
Dan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improved functionality.
Development

No branches or pull requests

3 participants