简体   繁体   中英

Service Fabric actors that receive events from other actors

I'm trying to model a news post that contains information about the user that posted it. I believe the best way is to send user summary information along with the message to create a news post, but I'm a little confused how to update that summary information if the underlying user information changes. Right now I have the following NewsPostActor and UserActor

public interface INewsPostActor : IActor
{
    Task SetInfoAndCommitAsync(NewsPostSummary summary, UserSummary postedBy);

    Task AddCommentAsync(string content, UserSummary, postedBy);
}

public interface IUserActor : IActor, IActorEventPublisher<IUserActorEvents>
{
    Task UpdateAsync(UserSummary summary);
}

public interface IUserActorEvents : IActorEvents
{
    void UserInfoChanged();
}

Where I'm getting stuck is how to have the INewsPostActor implementation subscribe to events published by IUserActor . I've seen the SubscribeAsync method in the sample code at https://github.com/Azure/servicefabric-samples/blob/master/samples/Actors/VS2015/VoiceMailBoxAdvanced/VoicemailBoxAdvanced.Client/Program.cs#L45 but is it appropriate to use this inside the NewsPostActor implementation? Will that keep an actor alive for any reason?

Additionally, I have the ability to add comments to news posts, so should the NewsPostActor also keep a subscription to each IUserActor for each unique user who comments?

Events may not be what you want to be using for this. From the documentation on events ( https://azure.microsoft.com/en-gb/documentation/articles/service-fabric-reliable-actors-events/ )

Actor events provide a way to send best effort notifications from the Actor to the clients. Actor events are designed for Actor-Client communication and should NOT be used for Actor-to-Actor communication.

Worth considering notifying the relevant actors directly or have an actor/service that will manage this communication.

Service Fabric Actors do not yet support a Publish/Subscribe architecture. (see Azure Feedback topic for current status.)

As already answered by charisk, Actor-Events are also not the way to go because they do not have any delivery guarantees.

This means, the UserActor has to initiate a request when a name changes. I can think of multiple options:

  • From within IUserAccount.ChangeNameAsync() you can send requests directly to all NewsPostActors (assuming the UserAccount holds a list of his posts). However, this would introduce additional latency since the client has to wait until all posts have been updated.

  • You can send the requests asynchronously. An easy way to do this would be to set a "NameChanged"-property on your Actor state to true within ChangeNameAsync() and have a Timer that regularly checks this property. If it is true, it sends requests to all NewsPostActors and sets the property to false afterwards. This would be an improvement to the previous version, however it still implies a very strong connection between UserAccounts and NewsPosts.

  • A more scalable solution would be to introduce the "Message Router"-pattern. You can read more about this pattern in Vaughn Vernon's excellent book "Reactive Messaging Patterns with the Actor Model" . This way you can basically setup your own Pub/Sub model by sending a "NameChanged"-Message to your Router. NewsPostActors can - depending on your scalability needs - subscribe to that message either directly or through some indirection (maybe a NewsPostCoordinator). And also depending on your scalability needs, the router can forward the messages either directly or asynchronously (by storing it in a queue first).

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