1

我正在努力解决持久性问题,但我还没有恢复演员的能力。

我的意图是通过它的 persistenceId 获取一个 Actor(我们在 DDD 中使用 GetById 获取一个实体的方式相同)。

我可以获取对 List 的引用并将其添加到 List Manager 中的变量中,但我正在寻找的是,一旦 Actor 死亡,如何获取 Actor 的当前状态(按事件恢复)以便可以进行修改。

如果我的问题不清楚,请告诉我

这是我到目前为止所做的:**命令和事件**

  using System;
    namespace AkkaPersistence
    {
       public class CreateNewList
        {
            public string ListName { get; private set; }
            public Guid UserId { get; private set; }
           public string ListId { get; set; }

           public CreateNewList(string listName, Guid userId, string listId)
            {
                ListName = listName;
                UserId = userId;
               ListId = listId;
            }
        }


        public class RemoveList
        {
            public string ListId { get; private set; }
            public Guid UserId { get; private set; }

            public RemoveList(string listId, Guid userId)
            {
                ListId = listId;
                UserId = userId;
            }
        }


        public class ListCreated
        {
            public string ListName { get; private set; }
            public Guid UserId { get; private set; }
            public string ListId { get; private set; }

            public ListCreated(string listName, Guid userId, string listId)
            {
                ListName = listName;
                UserId = userId;
                ListId = listId;
            }
        }


        public class ListRemoved
        {
            public Guid UserId { get; private set; }
            public string ListId { get; private set; }

            public ListRemoved(Guid userId, string listId)
            {

                UserId = userId;
                ListId = listId;
            }
        }
    }

**列表类**

   using System;
using Akka.Actor;
using Akka.Persistence;
namespace AkkaPersistence
{
   public class List: ReceivePersistentActor
   {
       public override string PersistenceId => "AKKANETLIST";

        private string Name {  get;  set; }

        private Guid CreatedBy { get; set; }

        private Guid ModifiedBy { get; set; }

        public List()
        {


            Recover<ListCreated>(evnt =>
            {
                Console.WriteLine(" List :: Recovery Hit'");
                Console.WriteLine("PID:{0}, Name {1}, CreatedBy:{2}, ModifiedBy{3}", PersistenceId, evnt.ListName, evnt.UserId, evnt.UserId);
                Name = evnt.ListName;
                CreatedBy = evnt.UserId;
                ModifiedBy = evnt.UserId;
            });




           Command<CreateNewList>(cmd =>
           {
               Console.WriteLine(" List :: Received Command 'CreateNewList'");
               var listCreated= new ListCreated(cmd.ListName,cmd.UserId, PersistenceId);

               Persist(listCreated, lc =>
               {
                   Console.WriteLine(" List::Event 'ListCreated' persisted");
                   Name = cmd.ListName;
                   CreatedBy = cmd.UserId;
                   ModifiedBy = cmd.UserId;
                  Sender.Tell(listCreated, ActorRefs.Nobody);
                   Console.WriteLine(" List::Event 'ListCreated' sent out");
               });

           });


            Command<RemoveList>(cmd =>
            {
                Console.WriteLine(" List :: Received Command 'RemoveList'");

                Console.WriteLine("PID:{0}, Name {1}, CreatedBy:{2}, ModifiedBy{3}",PersistenceId, Name, CreatedBy, ModifiedBy);
                var listRemoved = new ListRemoved(cmd.UserId,PersistenceId);

                Persist(listRemoved, lc =>
                {
                    Console.WriteLine(" List::Event 'ListRemoved' persisted");
                    ModifiedBy = cmd.UserId;
                    Sender.Tell(listRemoved, ActorRefs.Nobody);
                    Console.WriteLine(" List::Event 'ListRemoved' sent out");
                });

            });
        }
    }
}

** 列表管理器 **

using System;
using Akka.Actor;

namespace AkkaPersistence
{
    public class ListManager : ReceiveActor
    {

        public ListManager()
        {
            Receive<CreateNewList>(cmd =>
            {
                Console.WriteLine(" List Manager:: Received Command 'CreateNewList'");
                var newListRef = Context.ActorOf(Props.Create(typeof(List)));
                newListRef.Tell(cmd, Self);
                Console.WriteLine(" List Manager:: Command To Create New List sent to List Actor");
            });

            Receive<RemoveList>(cmd =>
            {
                Console.WriteLine(" List Manager:: Received Command 'RemoveList'");
                var newListRef = Context.ActorOf(Props.Create(() => new List()), "AKKANETLIST");
                newListRef.Tell(cmd, Self);
                Console.WriteLine(" List Manager:: Command To 'Remove List'  sent to List Actor");
            });


            Receive<ListCreated>(evnt =>
            {
                Console.WriteLine(" List Manager:: Event 'ListCreated' Received");
            });
        }
    }
}

** Program.cs ** 命名空间 AkkaPersistence { class Program { static void Main(string[] args) {

        var system = ActorSystem.Create("MySystem");
        var listManager = system.ActorOf<ListManager>("ListManager");


        // create command
        var newListId = Guid.NewGuid().ToString("N");
        var createCommand= new CreateNewList("Akka List 1", Guid.NewGuid(), newListId);
        listManager.Tell(createCommand);



        //remove Command

        var removeCommand = new RemoveList(newListId, createCommand.UserId);
        listManager.Tell(removeCommand);

        Console.ReadLine();


    }
}

}

** 控制台文本 **

[WARNING][1/21/2017 3:11:47 PM][Thread 0009][ActorSystem(MySystem)] NewtonSoftJsonSerializer has been detected as a default serializer. It will be obsoleted in Akka.NET starting from version 1.5 in the favor of Wire (for more info visit: http://getakka.net/docs/Serialization#how-to-setup-wire-as-default-serializer ). If you want to suppress this message set HOCON `akka.suppress-json-serializer-warning` config flag to on.
 List Manager:: Received Command 'CreateNewList'
 List Manager:: Command To Create New List sent to List Actor
 List Manager:: Received Command 'RemoveList'
 List Manager:: Command To 'Remove List'  sent to List Actor
 List :: Received Command 'CreateNewList'
 List :: Received Command 'RemoveList'
PID:AKKANETLIST, Name , CreatedBy:00000000-0000-0000-0000-000000000000, ModifiedBy00000000-0000-0000-0000-000000000000
 List::Event 'ListCreated' persisted
 List::Event 'ListCreated' sent out
 List Manager:: Event 'ListCreated' Received
 List::Event 'ListRemoved' persisted
 List::Event 'ListRemoved' sent out

** 更新 1 **2017-01-24

进一步努力,我能够获得基于名称的演员实例。为此,我需要创建 PersistenceId 作为命令的一部分,并使用持久性 Id 命名 Actor

通过这样做,我可以使用 Context.Child(Name) 来获取 Actor。

我正在 ListManager:Receive 中执行 Context.Stop(newListRef) 假设这将停止 List Actor 并在我使用 Context.Child(Name) 访问时强制它恢复,但这并没有发生,但不知何故列表状态是正确的. 不知道怎么做。

我将根据我今天从 Horusiath 收到的评论进行更多测试

4

1 回答 1

0

我可能不太明白你的问题,但是当你需要重新创建一个持久的演员时,你只需创建另一个具有相同PersistenceId.

这里唯一要记住的是,你不应该同时拥有一个以上的持久演员的活生生的实例PersistenceId。否则,您可能会以多个参与者同时尝试编写事件而告终,这可能会破坏事件流。

于 2017-01-24T07:18:25.943 回答