简体   繁体   中英

Rx.net and The Actor Model

I have a situation where I need to return an IObservable<T> from a method. It is to return a new value of object T Whenever it has changed.

The trigger that the object has changed will come from the actor system, in my example we are using Proto.Actor .

I have gotten an example to "work", however I feel it is not correctly implementing IObservable and will not allow for proper unsubscription etc.

My solution:

    public IObservable<T> Watch<T>(long id)
    {
        var subscriber = _actorFactory.GetActor<ObjectChangedActor>();
        var request = new ObjectWatchRequest(id);

        return Observable.Create<T>(async (observer, cancellationToken) =>
        {
            await Task.Run(async () =>
            {
                while (true)
                {
                    var response = await subscriber.RequestAsync<ObjectUpdatedResponse>(request, cancellationToken);
                    // once it gets past the above line, we have gotten notice that the object has been updated
                    var updatedObj = await Get<T>(id);
                    observer.OnNext(updatedObj);
                }
            }, cancellationToken);

            // will this ever be called?
            return Disposable.Create(() =>
            {
                Console.WriteLine("Disposal called");
            });
        });
    }

I feel like, despite the fact it "works" in that all updates are pushed to the subscriber, it will never be able to accurately dispose, and I don't feel like while (true) should ever be put in code, even when it is on a separate thread.

How would I best handle a list of messages coming back from the actor system and turning those into an IObservable that the user can dispose of (unsubscribe)?

You haven't provided a full working example of your code, which has made it difficult to give you a working solution that you can just copy and paste. However, I've made a cut-down version that I think you can probably work from.

You're right that your solution is not a good implementation.

Here's a basic version of your code that should work about right once you put your objects in:

public IObservable<T> Watch<T>(long id)
{
    return
        Observable
            .Defer(() =>
                from x in Observable.FromAsync(() => RequestAsync())
                from y in Observable.FromAsync(() => Get<T>(id))
                select y)
            .Repeat();
}

Let me know if this hits the mark for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM