These are chat archives for akkadotnet/akka.net

19th
Sep 2017
jalchr
@jalchr
Sep 19 2017 07:00
@Horusiath @Aaronontheweb Any thoughts about this http://proto.actor/blog/2017/06/24/money-transfer-saga.html ?
Michel van den Berg
@promontis
Sep 19 2017 08:36
@Horusiath in your akka cluster sharding demo (https://github.com/Horusiath/AkkaDemos/tree/master/cluster-sharding), did you try working with Remember Entities on? It seems to be working the first time you restart the system (all nodes down), but the second time none of the actors are recreated... is this a known issue?
Joshua Garnett
@joshgarnett
Sep 19 2017 13:56
Interesting, it appears that the Self reference is not available within callbacks? That seems different than what JVM Akka does.
Aaron Stannard
@Aaronontheweb
Sep 19 2017 13:57
it's because Self is resolved via a ThreadStatic reference
so it's meant to be used inside the scope of an actor
you need to close over it to use it in continuations
Joshua Garnett
@joshgarnett
Sep 19 2017 13:58
bleh :P
Aaron Stannard
@Aaronontheweb
Sep 19 2017 13:58
I'm not sure on the details of this too, btw, but I think it's also a difference with how CLR properties work vs. Scala ones
I think scala ones are essentially just fields, thus no need for a closure
so there's no underlying method being invoked
Joshua Garnett
@joshgarnett
Sep 19 2017 13:59
Does pipeTo support casting to the actual underlying type? Trying to work through the ergonomics of Ask
Aaron Stannard
@Aaronontheweb
Sep 19 2017 13:59
the Self property is really invoking a function under the hood
PipeTo just deals with objects
it's up to the receiving actor to handle it
shouldn't need to cast really
Joshua Garnett
@joshgarnett
Sep 19 2017 13:59
Got it, so the Receive should do the right thing?
Aaron Stannard
@Aaronontheweb
Sep 19 2017 13:59
correct
Joshua Garnett
@joshgarnett
Sep 19 2017 13:59
That makes sense
How does pipeTo handle faults within the task?
Aaron Stannard
@Aaronontheweb
Sep 19 2017 14:01
it'll return a Status.Failed message
if one of the preceding tasks fails
TBH though, the way I always do it
is I have a continuation between my Ask and my PipeTo where I put in some sort of custom error type
so I can handle timeouts and stuff with a message rather than bubbling up an exception
Joshua Garnett
@joshgarnett
Sep 19 2017 14:02
Got it
Aaron Stannard
@Aaronontheweb
Sep 19 2017 14:02
in complex scenarios, anyway
Joshua Garnett
@joshgarnett
Sep 19 2017 14:02
Got a snippet of what that looks like? Docs were pretty thin on pipeTo
Aaron Stannard
@Aaronontheweb
Sep 19 2017 14:02
in simple ones, like when I'm using Ask to get some data from inside the actor system to something external like an ASP.NET MVC response
dedicated PipeTo sample
that's an example where I'm handling HTTP status codes and packing up the downloaded data before I pipe it to an actor
Joshua Garnett
@joshgarnett
Sep 19 2017 14:06
Cool thanks
hmm, I almost wish we could just forward the entire typed Task over
Receive<Task<SomeResult>>(result => OnTaskSomeResult(result);
or something like that
Joshua Garnett
@joshgarnett
Sep 19 2017 14:44
        protected void PipeTaskResultTo<T>(Task<object> task, ICanTell recipient) {
            task.ContinueWith(tresult => {
                TaskResult<T> message;

                if (tresult.IsCanceled || tresult.IsFaulted) {
                    message = TaskResult<T>.Failure(tresult.Exception);
                }
                else {
                    if (tresult.Result is T) {
                        message = TaskResult<T>.Success((T) tresult.Result);
                    }
                    else {
                        message = TaskResult<T>.Failure(new Exception("Invalid type returned: " + tresult.GetType()));
                    }
                }
                recipient.Tell(message, ActorRefs.NoSender);

            }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
        }
Thinking maybe something like that
Joshua Garnett
@joshgarnett
Sep 19 2017 14:55
Put together as an extension it looks like this https://gist.github.com/joshgarnett/cb104904a552136d2f5731f5cfc41a45
Ismael Hamed
@ismaelhamed
Sep 19 2017 15:43
@joshgarnett @Aaronontheweb Don't you also have to avoid closing over the actor's reference when using future callbacks in scala?
http://doc.akka.io/docs/akka/current/scala/general/jmm.html#jmm-shared-state
Joshua Garnett
@joshgarnett
Sep 19 2017 15:44
State yes, but Self is typically safe
sender() you need to close over though
Ismael Hamed
@ismaelhamed
Sep 19 2017 15:44
right, self() != sender()
:)
Gaelan 'G' Harrington
@GSHarrington
Sep 19 2017 16:50

Brand new in the world of Akka. After I receive a timeout message. Is there a way to have my actor repeat the previous message instead of sending a PoisionPill like I'm doing now.
'private void Ready()
{

        Receive<01Message>(msg => Send01Message(msg));            
        Receive<ReceiveTimeout>(HandleTimeOut, null);
          this.SetReceiveTimeout(TimeSpan.FromSeconds(3));
    }

private void HandleTimeOut(ReceiveTimeout msg)
{

        Self.Tell(PoisonPill.Instance);
        Console.WriteLine("Time out received");
        log.Info(self + " has timedout!");
    }    

private void Send01Message(01Message msg)
{

    //do work
    }'
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 16:50
@promontis RememberEntities behavior changed a little between v1.2 and v1.3 - my example doesn't reflect those changes
@jalchr you can do Saga pattern as well in akka - however it will look a bit uglier (thanks to old akka.persistence API design)
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 17:00

@GSHarrington I see 3 ways here:

1st: After sending message schedule a timeout message like:

void Send(IActorRef target, obj msg, int attempt = 1) {
     retryTask.Cancel();
     target.Tell(msg);
     retryTask = Context.System.Scheduler.ScheduleTellOnceCancellable(timeout, Self, new Retry(msg, target, attempt), Self);
}

Receive<Retry>(retry => {
      if (retry.Attempt < Treshold) Send(retry.Target, retry.Message, retry.Attempt + 1);
});
2nd: use AtLeastOnceDelivery - this is pretty heavy-weight, as it uses persistence to guarantee retries even in face of failing nodes.
3rd: use Ask + Polly retry policies - while Ask is not the best thing to use between actors (it's slower and allocates some objects), sometimes it's not about performance, but simply getting things done ;)
Michel van den Berg
@promontis
Sep 19 2017 17:27
@Horusiath could you tell me a little bit more on those changes? I've really looked into how to make it work, but I ran out of options
Gaelan 'G' Harrington
@GSHarrington
Sep 19 2017 18:07
@Horusiath Thank you!
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 18:26
I'm not even sure if the problems you have are related to StartEntity (ofc not sure if you really need that feature either)
James World
@james-world
Sep 19 2017 21:04
Just posted the repo of my run through of Jason Robert's Akka.NET Persistence Pluralsight course. Updated the code from the course to .NET Core 2.0 and latest SqlServer and Hyperion bits, and used Serilog for logging.
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 21:13
@james-world don't use hyperion for persistence
James World
@james-world
Sep 19 2017 21:14
Why so?
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 21:14
James World
@james-world
Sep 19 2017 21:16
OK. What should I use?
(And more importantly how do I configure it?)
@Horusiath Not sure how to specify different serialization for remoting and persistence...
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 21:24
For persistence, having a well-defined schema is a plus i.e. Protobuf/Bond/MessagePack could do that. Also in akka serializers are bound based on type matching, this includes interfaces. You can mark your persistent events with some marker interface and then configure your custom serializer to use it.
Writing a custom serializer is a lot of ceremony though. For apps that don't need the performance, surely a json blob is good enough?
Bartosz Sypytkowski
@Horusiath
Sep 19 2017 21:27
probably - a custom serializer is essentially 2 methods (serialize/deserialize) and 2 properties (IncludeManifest - in 90% cases false and unique SerializerId, usually numbers above 1000 are free to use)
James World
@james-world
Sep 19 2017 21:49
@Horusiath Point of clarification - if I specify a custom serializer, does that get used for remoting serialization too? Or is there separate configuration for that?
James World
@james-world
Sep 19 2017 22:53
@Horusiath I've updated my code with custom serialization using MessagePack. I didn't use the Akka MessagePack package as a learning exercise. It was as you say, quite straightforward.