我正在努力解决持久性问题,但我还没有恢复演员的能力。
我的意图是通过它的 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 收到的评论进行更多测试