Akka.Net和内存持久

时间:2017-01-21 15:19:52

标签: akka.net akka.net-persistence

我试图让我的头脑坚持不懈,我还没有能够找回一个演员。

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

我可以获取对List的引用并将其添加到List Manager中的变量,但我要找的是一旦Actor死了如何让Actor获得其当前状态(Revovery By Events)以便修改可以完成。

如果我的问题不明确,请告诉我

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

  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 {     课程     {         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

进一步努力,我能够基于Name获取Actor的实例。 为此,我需要创建PersistenceId作为命令的一部分 使用持久性标识

命名Actor

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

我正在ListManager中执行Context.Stop(newListRef):接收假设这将停止List Actor并强制它在我使用Context.Child(Name)访问时恢复,但这不会发生,但不知何故列表国家是正确的。不确定如何。

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

1 个答案:

答案 0 :(得分:0)

我可能不太了解您的问题,但是当您需要重新创建持久性actor时,您只需使用相同的PersistenceId创建另一个actor实例。

这里唯一需要记住的是,你应该永远不会有多个持久性演员的生活实例,当时PersistenceId相同。否则,您可能会遇到多个尝试同时编写事件的actor,可能会破坏事件流。