如果我向Akka.NET actor发送一条消息,该消息是一个包含IActorRef的对象,然后保留该消息,写入日志表的JSON如下所示:
{"$id":"1","$type":"LearningAkka.Program+BindReference, LearningAkka","Reference":{"$id":"2","$type":"Akka.Actor.ActorRefBase+Surrogate, Akka","Path":"akka://LearningAkka/user/$b#1222898859"}}
如果我理解这一点,那只是对actor实例的引用;创建它所需的“道具”不会存储在此消息中。
奇怪的是,我我在重新启动应用后看到了那里的对象。但是,正如预期的那样,它不是在重启之前构建的。这位演员是从哪里来的? Akka Persistence是否找到了一个“足够相似”并且用它代替的演员?
以下C#测试应用程序创建一个对象,并发送一条消息将其绑定到另外三个之一。处理actor系统后,将从持久性(SQL Server)重新创建该对象,并检查引用。
我的预期行为是以下任何一种(我不确定什么是最合适的):
控制台输出:
[WARNING][27/05/2017 21:02:27][Thread 0001][ActorSystem(LearningAkka)] NewtonSoftJsonSerializer has been detected as a default serializer. It will be obsoleted in Akka.NET starting from version 1.5 in the favor of Hyperion (for more info visit: http://getakka.net/docs/Serialization#how-to-setup-hyperion-as-default-serializer ). If you want to suppress this message set HOCON `akka.suppress-json-serializer-warning` config flag to on.
From the first run B
[WARNING][27/05/2017 21:02:28][Thread 0001][ActorSystem(LearningAkka)] NewtonSoftJsonSerializer has been detected as a default serializer. It will be obsoleted in Akka.NET starting from version 1.5 in the favor of Hyperion (for more info visit: http://getakka.net/docs/Serialization#how-to-setup-hyperion-as-default-serializer ). If you want to suppress this message set HOCON `akka.suppress-json-serializer-warning` config flag to on.
From the second run B
C#:
using Akka.Actor;
using Akka.Event;
using Akka.Persistence;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearningAkka
{
class Program
{
static void Main(string[] args)
{
using (var actorSystem = ActorSystem.Create("LearningAkka"))
{
var referenceA = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the first run A")));
var referenceB = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the first run B")));
var referenceC = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the first run C")));
var actor = actorSystem.ActorOf(Props.Create(() => new TestActor()));
actor.Tell(new BindReference { Reference = referenceB });
actor.Tell(new CheckReference());
Console.ReadLine();
}
using (var actorSystem = ActorSystem.Create("LearningAkka"))
{
var referenceA = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the second run A")));
var referenceB = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the second run B")));
var referenceC = actorSystem.ActorOf(Props.Create(() => new TestReferencedActor("From the second run C")));
var actor = actorSystem.ActorOf(Props.Create(() => new TestActor()));
actor.Tell(new CheckReference());
Console.ReadLine();
}
}
public struct BindReference { public IActorRef Reference; }
public struct CheckReference { }
public sealed class TestActor : ReceivePersistentActor
{
public override string PersistenceId => "test hardcoded";
private IActorRef StoredFromMessage;
public TestActor()
{
Command<CheckReference>(m => StoredFromMessage.Tell(m));
Command<BindReference>(m => Persist(m, m2 => StoredFromMessage = m2.Reference));
Recover<BindReference>(m => StoredFromMessage = m.Reference);
}
}
public sealed class TestReferencedActor : ReceiveActor
{
public TestReferencedActor(string ourLabel)
{
Receive<CheckReference>(m => Console.WriteLine(ourLabel));
}
}
}
}
HOCON:
akka {
persistence {
journal {
plugin = "akka.persistence.journal.sql-server"
sql-server {
class = "Akka.Persistence.SqlServer.Journal.SqlServerJournal, Akka.Persistence.SqlServer"
connection-string = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=LearningAkka;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
schema-name = dbo
table-name = Journal
auto-initialize = on
}
}
snapshot-store {
plugin = "akka.persistence.snapshot-store.sql-server"
sql-server {
class = "Akka.Persistence.SqlServer.Snapshot.SqlServerSnapshotStore, Akka.Persistence.SqlServer"
connection-string = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=LearningAkka;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
schema-name = dbo
table-name = Snapshot
auto-initialize = on
}
}
}
}
有人可以评论一下这里的行为吗?谢谢。
答案 0 :(得分:0)
从序列化数据中可以看出 - 您的IActorRef指向此地址akka://LearningAkka/user/$b
。通常为未命名的演员放置$b
。因此,它将始终是您在actor系统根目录中创建的第二个未命名的actor(据我所知)。
所以你是对的 - 系统行为在这里是未定义的。