2017-01-21 23 views
1

我試圖讓我的頭部持久化,我還沒有能夠恢復演員。Akka.Net和在內存中的存在

我的意圖是通過它的persistenceId獲得一個Actor(與我們在DDD中使用GetById獲得一個實體的方式相同)。

我可以得到對List的引用並將它添加到列表管理器中的一個變量中,但我所尋找的是一旦演員死掉了如何獲取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 { 類節目 { 靜態無效的主要(字符串[]參數) {

 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

進一步的努力,我能夠根據名稱獲得Actor的實例。 爲此,我需要創建PersistenceId作爲命令的一部分,並且使用持久Id命名爲Actor

通過這樣做,我可以使用Context.Child(Name)來獲取Actor。

我在做一個ListManager中的Context.Stop(newListRef):接收假設這將停止List Actor並強制它恢復,當我使用Context.Child(Name)訪問但沒有發生時,但不知何故列表狀態是正確的。不知道如何。

我將以此爲基礎進行評論一些更多的測試,我今天收到來自Horusiath

回答

0

我可能不太明白你的問題,但是當你需要重新創建一個持久的演員,你只需用相同的創建另一個主角實例PersistenceId

這裏唯一要記住的是,你永遠不應該有一個持續演員的生活實例,當時他們的PersistenceId一樣。否則,您可能會以多個參與者嘗試同時寫入事件結束,可能會破壞事件流。

+0

Horusiath,感謝您的評論。我們如何知道是否有另一個具有相同持久性ID的actor?如果persistence id是在actor創建者之外創建的,並且我們命名Actor,那麼使用persistence id,我猜我們可以通過Context找到。子(Persistreneid),但是如果Persistence Id是在Actor內部創建的,有沒有什麼方法可以找到一個實例是否可用。 – TheMar

+0

如果您在actor名稱和持久性id之間沒有直接關係,您需要自己保持一個到另一個的映射。你可能做的其他事情是放棄演員生命週期管理到第三方插件,如[Akka.Cluster.Sharding](http://getakka.net/docs/clustering/cluster-sharding)。 – Horusiath

+0

我會看看Akka.Cluster.Sharding,從另一篇文章的評論中,它提供了一些我正在尋找的流程。謝謝 – TheMar