Skip to content

Instantly share code, notes, and snippets.

@finnnewick-justgiving
Last active June 6, 2016 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save finnnewick-justgiving/b0167b55a33d0259ec7907d38fbc2ed2 to your computer and use it in GitHub Desktop.
Save finnnewick-justgiving/b0167b55a33d0259ec7907d38fbc2ed2 to your computer and use it in GitHub Desktop.
PersistentFSM Test Question
using System;
using System.Collections.Immutable;
using Akka.Actor;
using Akka.Persistence;
using Akka.Persistence.Fsm;
using Akka.TestKit.NUnit;
using NUnit.Framework;
namespace PersistentTest.Tests
{
public enum TestActorState
{
Counting,
FinishedCounting
}
public class TestActorData
{
public int TotalCount { get; set; }
}
public class CountedEvent {
public int Total { get; set; }
public CountedEvent(int total)
{
Total = total;
}
public override string ToString()
{
return $"{nameof(CountedEvent)} - Total: {Total}";
}
}
public class CountedTooOftenEvent
{
public override string ToString()
{
return $"{nameof(CountedTooOftenEvent)}";
}
}
public class CountCommand
{
public override string ToString()
{
return $"{nameof(CountCommand)}";
}
}
public class TestCountingActor : PersistentFSM<TestActorState, TestActorData, object>
{
public override string PersistenceId => "testActorId";
public TestCountingActor()
{
StartWith(TestActorState.Counting, new TestActorData());
When(TestActorState.Counting,
(e, state) =>
{
Console.WriteLine($"Handling {e.FsmEvent}");
if (e.FsmEvent is CountCommand)
{
Console.WriteLine($"Counting from {e.StateData.TotalCount}");
if (e.StateData.TotalCount > 2)
{
return GoTo(TestActorState.FinishedCounting);
}
return Stay()
.Applying(new CountedEvent(e.StateData.TotalCount + 1));
}
return state;
});
When(TestActorState.FinishedCounting,
(e, state) =>
{
Console.WriteLine($"Sorry, stopped counting!");
return Stop().Applying(new CountedTooOftenEvent());
});
}
protected override TestActorData ApplyEvent(object e, TestActorData data)
{
if (e.GetType() == typeof(CountedEvent))
{
Console.WriteLine($"Counted {e}");
return new TestActorData { TotalCount = ((CountedEvent)e).Total };
}
return data;
}
protected override void OnRecoveryCompleted() { }
}
public class TestScenario : TestKit
{
private const int ActorInstanceId = 1;
public TestScenario() : base("akka.suppress-json-serializer-warning = true")
{
}
[Test]
public void Then_It_Should_Work()
{
var testActor = ActorOfAsTestActorRef<TestCountingActor>(Props.Create<TestCountingActor>(), "MyTestActor");
Watch(testActor);
var journal = Persistence.Instance.Apply(Sys as ExtendedActorSystem).JournalFor(null);
journal.Tell(new WriteMessages(new[]
{
new Akka.Persistence.AtomicWrite(ImmutableList.Create<IPersistentRepresentation>(
new Persistent(new CountedEvent(1), 1, "testActorId"),
new Persistent(new CountedEvent(2), 2, "testActorId"),
new Persistent(new CountedEvent(3), 3, "testActorId"),
new Persistent(new PersistentFSMBase<TestActorState, TestActorData, object>.StateChangeEvent(TestActorState.FinishedCounting, null), 4, "testActorId")
))
}, testActor, ActorInstanceId));
Console.WriteLine($"Done telling journal");
testActor.Tell(new CountCommand());
ExpectTerminated(testActor);
}
}
/*
Failed: Timeout 00:00:03 while waiting for a message of type Akka.Actor.Terminated Terminated akka://test/user/MyTestActor.
at NUnit.Framework.Assert.Fail(String message, Object[] args)
at Akka.TestKit.TestKitBase.InternalExpectMsgEnvelope[T](Nullable`1 timeout, Action`2 assert, String hint, Boolean shouldLog)
at Akka.TestKit.TestKitBase.InternalExpectMsgEnvelope[T](Nullable`1 timeout, Action`1 msgAssert, Action`1 senderAssert, String hint)
at Akka.TestKit.TestKitBase.InternalExpectMsg[T](Nullable`1 timeout, Action`1 msgAssert, String hint)
at Akka.TestKit.TestKitBase.ExpectTerminated(IActorRef target, Nullable`1 timeout, String hint)
at PersistentTest.Tests.TestScenario.Then_It_Should_Work() in d:\GG.Service.IssuerLookup\PersistentTest\PersistentTest.Tests\Class1.cs:line 139
Done telling journal
Counted CountedEvent - Total: 1
Counted CountedEvent - Total: 2
Counted CountedEvent - Total: 3
Handling CountCommand
Counting from 3
Counted CountedEvent - Total: 1
[ERROR][06/06/2016 15:57:35][Thread 0004][akka://test/user/MyTestActor] Object reference not set to an instance of an object.
Cause: System.NullReferenceException: Object reference not set to an instance of an object.
at Akka.Persistence.Eventsourced.PeekApplyHandler(Object payload)
at Akka.Persistence.Eventsourced.CommonProcessingStateBehavior(Object message, Action`1 onWriteMessageComplete)
at Akka.Persistence.Eventsourced.<ProcessingCommands>b__90_0(Receive receive, Object message)
at Akka.Persistence.Eventsourced.AroundReceive(Receive receive, Object message)
at Akka.Actor.ActorCell.ReceiveMessage(Object message)
at Akka.Actor.ActorCell.Invoke(Envelope envelope)
Counted CountedEvent - Total: 1
Counted CountedEvent - Total: 2
Counted CountedEvent - Total: 3
[WARNING][06/06/2016 15:57:38][Thread 0016][akka://test/user/testActor1] DeadLetter from [akka://test/user/testActor1] to [akka://test/user/testActor1]: <Received dead system message: <DeathWatchNotification>: TestActor[akka://test/user/MyTestActor], ExistenceConfirmed=True, AddressTerminated=False>
[WARNING][06/06/2016 15:57:38][Thread 0016][akka://test/user] DeadLetter from [akka://test/user] to [akka://test/user]: <Received dead system message: <DeathWatchNotification>: [akka://test/user/testActor1], ExistenceConfirmed=True, AddressTerminated=False>
[WARNING][06/06/2016 15:57:38][Thread 0016][akka://test/user] DeadLetter from [akka://test/user] to [akka://test/user]: <Received dead system message: <DeathWatchNotification>: TestActor[akka://test/user/MyTestActor], ExistenceConfirmed=True, AddressTerminated=False>
[WARNING][06/06/2016 15:57:38][Thread 0016][akka://test/user] DeadLetter from [akka://test/user] to [akka://test/user]: <Received dead system message: <DeathWatchNotification>: [akka://test/user/$b], ExistenceConfirmed=True, AddressTerminated=False>
[INFO][06/06/2016 15:57:38][Thread 0015][akka://test/user/testActor1] Message DeathWatchNotification from akka://test/user/testActor1 to akka://test/user/testActor1 was not delivered. 1 dead letters encountered.
[INFO][06/06/2016 15:57:38][Thread 0015][akka://test/user] Message DeathWatchNotification from akka://test/user to akka://test/user was not delivered. 2 dead letters encountered.
[INFO][06/06/2016 15:57:38][Thread 0015][akka://test/user] Message DeathWatchNotification from akka://test/user to akka://test/user was not delivered. 3 dead letters encountered.
[INFO][06/06/2016 15:57:38][Thread 0015][akka://test/user] Message DeathWatchNotification from akka://test/user to akka://test/user was not delivered. 4 dead letters encountered.
DeadLetter from [akka://test/system] to [akka://test/system]: <<DeathWatchNotification>: [akka://test/system/EventStreamUnsubscriber-1], ExistenceConfirmed=True, AddressTerminated=False>
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment