Akka.Net и в памяти постоянство
Я пытаюсь отвлечься от упорства, и я еще не могу восстановить актера.
Мое намерение состоит в том, чтобы получить Actor по его persistenceId (так же, как мы получаем Entity, используя GetById в DDD).
Я могу получить ссылку на 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 {класс 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 персистентности.
Делая это, я мог бы использовать Context.Child(Name), чтобы получить Actor.
Я делаю Context.Stop(newListRef) в ListManager: Получите, предполагая, что это остановит субъект List и заставит его восстанавливаться, когда я получаю доступ с помощью Context.Child(Name), но этого не происходит, но каким-то образом состояние списка корректно, Не уверен как.
Я сделаю еще один тест на основе комментария, который я получил сегодня от Хорусиата
1 ответ
Возможно, я не совсем понимаю ваш вопрос, но когда вам нужно воссоздать персистентного актера, вы просто создаете другой экземпляр актера с тем же PersistenceId
,
Единственное, что нужно иметь в виду, это то, что у вас никогда не должно быть более одного живого экземпляра постоянного актера с одним и тем же PersistenceId
в это время. В противном случае вы можете закончить тем, что несколько действующих лиц пытаются одновременно писать события, что может повредить поток событий.