These are chat archives for akkadotnet/akka.net

25th
Jun 2018
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 05:44
@OnurGumus I think so. I can make it an effect, just need a bit of time to work over it.
Onur Gumus
@OnurGumus
Jun 25 2018 09:16
@Horusiath I was trying your persistence example. Few interesting findings. Despide that you set System.Object = hyperion, akka still falls back to built in json serializer. The serialization succeeds but deserialization fails.\
I have added a plain newtonsoft serializer then both serializer and deserializer succeeds
I wonder why akka still prefers json, for DU.
if I force it serialization-bindings {"Program+CounterMessage, ConsoleApp47, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" = newton } then it works
Simon McConnell
@Unthred
Jun 25 2018 09:35
Hey guys, sorry to bother you but there is something I am just failing to grasp.... I am looking at the Remoting example in the documentation and both Deployer and DeployTarget use localhost as their address...
Can I run the Deployer and when the DeployTarget connects to the Deployer get its address then (as I wont know it aforehand in the system I want to create)
So the line of code Props.Create(() => new EchoActor()).WithDeploy(Deploy.None.WithScope(new RemoteScope(remoteAddress)))
I want to get remoteAddress from then incomming DeployTarget
Onur Gumus
@OnurGumus
Jun 25 2018 09:36
@Unthred I did not understand your last sentence.
Simon McConnell
@Unthred
Jun 25 2018 09:37
@OnurGumus so i nthe docs remoteAddress is hardcoded
Onur Gumus
@OnurGumus
Jun 25 2018 09:38
And you need some sort of discovery?
Simon McConnell
@Unthred
Jun 25 2018 09:38
@OnurGumus Sorry - So in the docs remote Address is hard coded to be var remoteAddress = Address.Parse("akka.tcp://DeployTarget@localhost:8090"); I want to be able to get that from theincomming connection
@OnurGumus So I would know the address of the server the remote actor is going to connect to but in the server code I do not know the address is the remote actor until it connects.... does that make sense?
Onur Gumus
@OnurGumus
Jun 25 2018 09:43
Yeah
@Unthred have you considered using clusters ?
by using clusters your deployer will be aware of any new joiner
Simon McConnell
@Unthred
Jun 25 2018 09:45
@OnurGumus I have been looking at clusters but I was trying to get remoting working first....baby steps.....should I just go straight to clusters?
Onur Gumus
@OnurGumus
Jun 25 2018 10:04
@Unthred yes!
@Horusiath I noticed there is no API to make persistenceid different than actor name in akkling.
Simon McConnell
@Unthred
Jun 25 2018 10:04
@OnurGumus ok thanks will do
Simon McConnell
@Unthred
Jun 25 2018 11:47
@OnurGumus Got 2 cluster nodes talking to each other......exactly what I wanted. Thanks sooo much for your help!
Onur Gumus
@OnurGumus
Jun 25 2018 12:18
:)
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 12:18
@OnurGumus yes, mostly because originally persistenceId is an actor field, that must be set during actor creation (in constructor) - since in akkling actors are neither classes nor they can have fields, I've made a compromise and set this value arbitrarily
Onur Gumus
@OnurGumus
Jun 25 2018 12:19
is there a way to work it around ?
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 12:19
in future - if i.e. Akkling will move towards API similar to akka.typed - this value should be able to be set directly during creation
not right now, this could be changed once @zbynek001 PR will be merged (see #3524)
Onur Gumus
@OnurGumus
Jun 25 2018 12:22
How is defaultSerializer is set?
Appearantly for SQLite persistence the default serializer is set to json.
So you cannot set a serializer for "System.Object" = hyperion
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 12:34
@OnurGumus if I remember correctly some time ago there was a PR for persistence, which allowed to override default serializer for persistence plugins - you may specify akka.peristence.journal.sql-server.serializer = hyperionor something like that to override default serializer only for persistence
but again - be aware that Hyperion for persistence is not a good idea - I've wrote about that in http://bartoszsypytkowski.com/akka-persistence-most-common-misconceptions/
Greatsamps
@Greatsamps
Jun 25 2018 13:03

Hey guys. I am having some stability issues with Akka Cluster. I have an application which comprises of 4 microservices which are running in their own process. All 4 are running on the same server, which has not peaked above 50% CPU usage. What we are seeing is overtime some nodes become unreachable, and after a bit of flapping stabalise.

it happened just a moment ago, and one of the nodes in question was using a fair bit of CPU (30%), but it was far from being pegged. It almost seems that there is a thread contention issue, and whatever thread the cluster heartbeat is running on, has the same priority as everything else and as such might have to wait a bit.

am i along the right lines here?

any way to make it more stable?

Onur Gumus
@OnurGumus
Jun 25 2018 14:30
@Horusiath it is a bit confusing though, specifying a default serializer for persistence effectively overrides System Object = serializer
Aaron Stannard
@Aaronontheweb
Jun 25 2018 14:46
@Greatsamps are you running Akka.Cluster.Sharding?
and which version of Akka.NET are you using?
Greatsamps
@Greatsamps
Jun 25 2018 14:59
Hey @Aaronontheweb nice to hear from you! No, still using cluster singletons for this app. Running Akka 1.38, and also moved back to using Json.Net serializer rather than hyperion to try and reduce possible problem areas
Aaron Stannard
@Aaronontheweb
Jun 25 2018 15:00
@Greatsamps I'll DM you with some more questions \
nathvi
@nathvi
Jun 25 2018 15:06
I have a pretty simple noob question...
Aaron Stannard
@Aaronontheweb
Jun 25 2018 15:08
go for it
nathvi
@nathvi
Jun 25 2018 15:09
namespace KeyServiceTemplate.Actors
{
    public class HitMessage
    {
        public int Damage { get; }

        public HitMessage(int damage)
        {
            Damage = damage;
        }
    }

    public class CauseActorErrorMessage
    {
    }

    public class DisplayStatusMessage
    {
    }

    public class PlayerActor : ReceivePersistentActor
    {
        int _playerHealth = 100; 
        string _playerName { get; } 
        public override string PersistenceId => _playerName;

        public PlayerActor(string playerName)
        {
            _playerName = playerName;
            Command<HitMessage>(msg => HitMessageHandler(msg));
            Command<CauseActorErrorMessage>(msg => CauseActorErrorMessageHandler());
            Command<DisplayStatusMessage>(msg => DisplayStatusMessageHandler());
            Recover<HitMessage>(msg => HitMessageRecoveryHandler(msg));
            Console.WriteLine($"PlayerActor {_playerName} created. Health is {_playerHealth}");
        }

        private void HitMessageRecoveryHandler(HitMessage msg)
        {
            Console.WriteLine($"Player {_playerName} replaying hit message {msg} from journal.");
            _playerHealth -= msg.Damage;
        }

        private void DisplayStatusMessageHandler()
        {
            Console.WriteLine();
            Console.WriteLine($"Player name is {_playerName}, Health is {_playerHealth}");
            Console.WriteLine();
        }

        private void CauseActorErrorMessageHandler()
        {
            throw new Exception();
        }

        private void HitMessageHandler(HitMessage hitMessage)
        {
            Persist(hitMessage, msg => { Console.WriteLine("Hit message was persisted."); });
            Persist(hitMessage, msg => { Console.WriteLine($"Hitting with damage of {hitMessage.Damage}."); });
            _playerHealth -= hitMessage.Damage;
            Console.WriteLine();
        }
    }
}
I'm using this code, with a default disk persistent store.
When I tell this actor damage, it does the right thing. When I cause an artificial error with the CauseActorErrorMessage, it restarts the actor, but the HitMessageRecoveryHandler is called twice for every one hit message, why is this?
Wait
lol
me-slove
@me-slove
Jun 25 2018 15:13
because you are persisting two messages in your hit handler
nathvi
@nathvi
Jun 25 2018 15:13
I see that now XD
me-slove
@me-slove
Jun 25 2018 15:13
good thing to test though :)
nathvi
@nathvi
Jun 25 2018 15:14
Right after I got done posting it, I saw that XD
Onur Gumus
@OnurGumus
Jun 25 2018 15:20
Is there way to start a cluster without opening a port ? The reason I ask is I would like to use utilities like Passivation and DistributedPubSub, but in my case I have one node only. Does it make sense ?
me-slove
@me-slove
Jun 25 2018 15:22
seems a little against the cluster model since the purpose is to provide location transparency but there may be a test mode or some such
Onur Gumus
@OnurGumus
Jun 25 2018 15:23
I don't need a cluster, I just want to make use if its utilities.
Vagif Abilov
@object
Jun 25 2018 15:24
Why do you need passivation in a non-clustered scenario? Can you just stop?
nathvi
@nathvi
Jun 25 2018 15:30
Here's my refactor of the code from before
namespace KeyServiceTemplate.Actors
{
    public class HitMessage
    {
        public int Damage { get; }

        public HitMessage(int damage)
        {
            Damage = damage;
        }
    }

    public class CauseActorErrorMessage
    {
    }

    public class DisplayStatusMessage
    {
    }

    public class PlayerActor : ReceivePersistentActor
    {
        int _playerHealth = 100; 
        string _playerName { get; } 
        public override string PersistenceId => _playerName;

        public PlayerActor(string playerName)
        {
            _playerName = playerName;
            Command<HitMessage>(msg => HitMessageHandler(msg));
            Recover<HitMessage>(msg => HitMessageRecoveryHandler(msg));
            Command<CauseActorErrorMessage>(msg => CauseActorErrorMessageHandler());
            Command<DisplayStatusMessage>(msg => DisplayStatusMessageHandler());
            Console.WriteLine($"PlayerActor {_playerName} created. Health is {_playerHealth}");
        }

        private void HitMessageHandler(HitMessage hitMessage)
        {
            Persist(hitMessage, msg => { Console.WriteLine("Hit message was persisted."); });
            Console.WriteLine($"Hitting with damage of {hitMessage.Damage}.");
            HitMessageAction(hitMessage);
            Console.WriteLine();
        }

        private void HitMessageRecoveryHandler(HitMessage msg)
        {
            Console.WriteLine($"Player {_playerName} replaying hit message {msg} from journal.");
            HitMessageAction(msg);
        }

        private void HitMessageAction(HitMessage hitMessage)
        {
            _playerHealth -= hitMessage.Damage;
        }

        private void DisplayStatusMessageHandler()
        {
            Console.WriteLine();
            Console.WriteLine($"Player name is {_playerName}, Health is {_playerHealth}");
            Console.WriteLine();
        }

        private void CauseActorErrorMessageHandler()
        {
            throw new Exception();
        }
    }
}
It seems like the using the HitMessageAction for both handling normal client messages and for recovering would be a generalized pattern in the API. Is there something I'm missing?
Is there some sort of RecoverableCommand ?
Onur Gumus
@OnurGumus
Jun 25 2018 15:35
@nathvi this is a design thing. So ideally you should segregate your messages into 2 categories. Events and Commands.
A command is the incoming message, a request that may be processed or failed whereas an event represents something that is already happened.
nathvi
@nathvi
Jun 25 2018 15:37
So there is processing of live messages, and processing of old messages.
Aaron Stannard
@Aaronontheweb
Jun 25 2018 15:37
akkadotnet/akka.net#3527 - this is ready for review I think
Onur Gumus
@OnurGumus
Jun 25 2018 15:37
A typical command processing happens this way-> Validate command -> create one or more events from a command, persist the event, apply the event, publish the event.
this way on recovery you will send your events to your ApplyEvent.
and you will not persist commands.
nathvi
@nathvi
Jun 25 2018 15:40
Right, so the "Apply Event" part is probably what I'm thinking about. It seems like this could be wrapped at a higher level.
Onur Gumus
@OnurGumus
Jun 25 2018 15:41
in your case "Hit" is a Command, and LifeReduced is an event.
Or it could be Killed.
So you get Hit as a command validate and decide which event you want to generate, LifeReduced or Killed, then you Persist it , Apply it (change the state here) and optionally publish the event to listeners.
on recovery you will be replaying a series of LifeReduced events.
and changing the state once more.
Aaron Stannard
@Aaronontheweb
Jun 25 2018 15:45
@zbynek001 nice work on the sharding PR
nathvi
@nathvi
Jun 25 2018 15:56
So the only difference between events and commands is:
Commands are messages that haven't been processed by the actor and events are commands that have been processed by the actor?
Onur Gumus
@OnurGumus
Jun 25 2018 15:57
Commands can are directives and can be rejected. Events represents an absolute decision is taken as a result of a Command they must be persisted and no more going back from it.
In a sense An actor is a transformer of Commands to Events in terms of event sourcing.
zbynek001
@zbynek001
Jun 25 2018 16:01
@Aaronontheweb thx. I even have some more stuff for sharding, improving graceful shutdown of it, not sure if I should put it in PR, since it's not part of akka
nathvi
@nathvi
Jun 25 2018 16:01
So, what's wrong with just having a command handler, persisting the command, and then handling it?
Like in my refactored code, it will persist and recover just fine.
Onur Gumus
@OnurGumus
Jun 25 2018 16:05
@nathvi suppose you have a TransferMoneyCommand and you are calling an external service as a result of that. If you don't do event and command segregation you may end up with money being transferred each time on recovery.
What I mention is the event sourcing pattern. Weather you want to apply the pattern or not is your decision.
Edson Flores Palma
@Efp95
Jun 25 2018 16:06
Hello, why was Akka.DI.Unity package labeled as deprecated?
https://github.com/AkkaNetContrib/Akka.DI.Unity
nathvi
@nathvi
Jun 25 2018 16:08
@OnurGumus , sorry, I'm having a hard time following. Can you refactor some of my code to show me why I would need it?
Onur Gumus
@OnurGumus
Jun 25 2018 16:09
Create to types of messages "Hit" and "LifeReduced"
then define a method calld AppyLifeReduced(LifeReduced e)
on your receive handler when you get a hit message create a new LifeReduced instance.
then Persist(lifeReduced, e =>ApplyLifeReduced(e); });
in ApplyLifeReduced method lower the life.
that's all
ah and point to ApplyLifeReduced in your recovery
you may also consider creating a base Event class
nathvi
@nathvi
Jun 25 2018 16:12
I'm not sure what that accomplishes. It seems like it's duplicating functionality I already have.
Onur Gumus
@OnurGumus
Jun 25 2018 16:14
well if you are happy with your own code, you can forget about what I said :)
nathvi
@nathvi
Jun 25 2018 16:16
I guess my question is, at least in my code, does applying this pattern give me any extra functionality that I don't have already?
Right now, I can handle the hit messages, and recover on an actor failure. What do I gain by applying this pattern?
Onur Gumus
@OnurGumus
Jun 25 2018 16:17
@nathvi You have asked this question: It seems like the using the HitMessageAction for both handling normal client messages and for recovering would be a generalized pattern in the API. Is there something I'm missing?
Is there some sort of RecoverableCommand ?
And what I mentioned solves your question.
nathvi
@nathvi
Jun 25 2018 16:17
It seems like an overly convoluted way to do it.
Onur Gumus
@OnurGumus
Jun 25 2018 16:18
Then feel free to do as you like.
me-slove
@me-slove
Jun 25 2018 16:18
I think the main point that Onur is making is that you may not have 1 to 1 alignment between commands and events. Also, you most certainly want to separate state changes from actions (e.g. commands). In other words the "hit" command may change your health, change the screen background color, etc. If you are recovering, you may, or may not, want to update the screen
think doom/quake where the screen showed you bleeding for example
nathvi
@nathvi
Jun 25 2018 16:23
Right, but if you notice in the code I posted, the HitMessageHandler calls the HitMessageAction and wraps the displaying of the event around it. The recovery handler does the same thing, thereby avoiding the unwanted effect of having the display code interfere with the recovery process.
The only things that are different between the handler and the recover method is the code before and after the basic state change occurs. I believe this can be encapsulated in a clean way by building it straight into the akka api
for example something like a RecoverableCommand Method
me-slove
@me-slove
Jun 25 2018 16:27
@nathvi to answer your earlier question, in your code, no real difference. I have seen much more complicated recovery though so just saying, consider splitting them up and since it becomes application code, it's why they probably would not do it for the general case
nathvi
@nathvi
Jun 25 2018 16:28
So there would be Before and After delegates for both the handler, and the recover methods.
So my code is not complicated enough to take advantage of the pattern? What would I need to add in order to see the benefits?
Onur Gumus
@OnurGumus
Jun 25 2018 16:33
@nathvi suppose the damage is based on the time of the day. If current time is 12, you get 12 damage , if it is 1 then you get 1 damage. If you don't do the translation from commands to events then on reply your state will be different.
however with events you can actually record the actual damage.
nathvi
@nathvi
Jun 25 2018 16:35
humm...
so, in the model that I'm thinking of, all of the logic to send to the HitMessageAction happens before the HitMessageAction is called in the normal message handler, which is why I propose a Before and After delegate . Before and after referencing the state change action that actually causes the internal state of the actor to change.
This whole pattern can be wrapped.
me-slove
@me-slove
Jun 25 2018 16:40
Sure. Lots of ways to skin the cat
nathvi
@nathvi
Jun 25 2018 16:40
IMHO, it would be cleaner to include a methodthat wraps the pattern, rather than having to do it manually over and over
Like including a method of RecoverableCommand
me-slove
@me-slove
Jun 25 2018 16:42
@Aaronontheweb will probably take a look at this and consider your idea.
nathvi
@nathvi
Jun 25 2018 16:42
@Aaronontheweb , plz let me know if this is something you'd be interested in exploring.
haha, just had the same idea.
nathvi
@nathvi
Jun 25 2018 16:53
something like this for the signature, idk
void PersistentCommand<T>
            (
            Action<T> stateChanger,
            Action<T> commandHandlerBefore,
            Action<T> commandHandlerAfter,
            Action<T> persistHandlerBefore,
            Action<T> persistHandlerAfter,
            Predicate<T> shouldHandle = null)
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 16:54
@zbynek001 you can always send a PR or describe your proposal in form of a github issue
@nathvi have you checked PersistentFSM - it sounds, like it could cover the cases you're talking about
nathvi
@nathvi
Jun 25 2018 16:58
@Horusiath , I have not. I'll check it out.
What does FSM mean?
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 17:01
Finite State Machine
essentially it's a DSL for building finite state machines that are able to persist info about state changes in durable manner (so i.e. if your actor has been restared, upon recovery it will start from the point it ended up in a state graph) and validate correct state changes
Edson Flores Palma
@Efp95
Jun 25 2018 17:35
Hello, why was Akka.DI.Unity package labeled as deprecated?
https://github.com/AkkaNetContrib/Akka.DI.Unity
nathvi
@nathvi
Jun 25 2018 18:46
What do you gain by modeling actors as an FSM?
@Horusiath
Arjen Smits
@Danthar
Jun 25 2018 19:05
@Efp95 because we no longer officially maintain it. At least the core team doesn't. Also i think we deprecated a few plugins. Because they where at some point contributed by someone. But they never quite worked. And the original author was gone with the wind.
If your interested in picking it up. Be my guest :)
Rodger Brennan
@rodgerbrennan
Jun 25 2018 19:30
I'm trying to figure out how to effectively create and use a read model. Assuming a Pseudo object like Person{name:string, email:string} I have a ReceivePersistentActor with commands for creating and changing properties along with persisting the matching events. What I'm gathering from reading docs and other projects is that I would want a UnTypedActor that reacts to a GetPerson message by hydrating a Person object and returning it? Does that seem like the correct pattern to implement assuming I have a WebApi that should return a Person as json?
Arsene Tochemey GANDOTE
@Tochemey
Jun 25 2018 20:18
Hello Geeks has we gotten the hocon netcore appsettings.json compatible?
Bartosz Sypytkowski
@Horusiath
Jun 25 2018 20:20

@nathvi lets say that most of the stateful problems are best to be composed as state machines. Almost all network protocols are state machines. It can also be used in business cases i.e. simple behaviors like user's ability to make certain actions only when that user is either anonymous or authorized.

In normal situation people tend to apply convoluted checks and redirections via aspect oriented programming to make authorization checking on every single action possible. What if you'd just define two behaviors with their own sets of message handlers, one for anonymous users and one only available for authorized ones? No need to check on every try, since if user's status is unathorized, it doesn't even know how to react to appropriate messages. Another example would be a game mechanic, where certain actions are not available i.e. when player is out of combat, in seat reservation system (as seat can be free, reserved, during reservation or payed) etc.

Akka has this available by default by allowing to switch behavior using Become method. FSM are just more structured approach to this, esspecially when state graph grows big.