These are chat archives for akkadotnet/akka.net

5th
Oct 2017
Bart de Boer
@boekabart
Oct 05 2017 07:50
@ayoung IIRC it is not supported at all (serialization issues with at least one of the serializers)
Arjen Smits
@Danthar
Oct 05 2017 08:56
@ayoung @boekabart Im not aware of any issues? If you use the same serializer on each side, it should not be an issue. Best approach would be to use protobuff all the way through.
/cc @alexvaluyskiy ?
Roman Golenok
@shersh
Oct 05 2017 09:45
Guys, is Akka.IO ready for production?
I still see TBD in documantation for classes.
Alex Valuyskiy
@alexvaluyskiy
Oct 05 2017 09:54
@shersh yes, it is ready. TBD is related only for XML Documentation, not for the API itself
Paweł Bańka
@pmbanka
Oct 05 2017 10:00

Hi, I have a question related to Stash. I don't understand this piece of docs:

The IWithUnboundedStash interface implementation of PreRestart will call UnstashAll(), which is usually the desired behavior.

(http://getakka.net/articles/actors/receive-actor-api.html#stash) Does this happen automagically when I implementIWithUnboundedStash on my actor? Where is this logic defined? I can't find it...

yeah, seems like it, since BeforeIncarnated is a

Plugin behavior applied to underlying <paramref name="actor"/> instance before the actor is being recycled.

Paweł Bańka
@pmbanka
Oct 05 2017 10:06
While I'm at it, another question - why is UntypedActor API "recommended for C# 7 users"? Because of better switch support?
Aaron Stannard
@Aaronontheweb
Oct 05 2017 13:07
@shersh yep, we use it in our products
@pmbanka I still use ReceiveActor mostly myself
but yeah, C# 7 makes working with the UntypedActor much more bearable
but ReceiveActor can do things switch cannot, such as matching on generics
Paweł Bańka
@pmbanka
Oct 05 2017 13:09
thanks @Aaronontheweb. The docs left me quite confused about the difference and whether one of them should be preferred (and why)
Bart de Boer
@boekabart
Oct 05 2017 13:23
So is the bottom line that ReceiveActor is likely to be 'heavier' than necessary for C# 7 code?
Aaron Stannard
@Aaronontheweb
Oct 05 2017 13:24
@pmbanka which page of the docs?
Paweł Bańka
@pmbanka
Oct 05 2017 13:28
@Aaronontheweb the workflow was like that: 1) click http://getakka.net/articles/actors/receive-actor-api.html, start reading. It starts with actors, blah blah, then defining, props, all that jazz. Ok, but I see there is also another API. So I go to 2) http://getakka.net/articles/actors/untyped-actor-api.html, see the beginning is the same, scroll down, creating actors, props, etc. 3) realize that these APIs seem very similar, start hunting down what is the difference, notice OnReceive in one and pattern match in the other one 4) notice the info on top of UntypedActor API page about C# 7, confirming it is mostly about the switch (?)
I think it would be nice to put some section somewhere explainig why are there 2 different APIs, what is the difference and pros/cons
especially since googling akka.net receive actor vs untyped actor does not return anything about the why
Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:05
@pmbanka well then
I've been overdue for some technical blog posts on Petabridge's site
sounds like a good one lol
on the official website we mostly just try to give you an explanation for how things work
and what the different tools are meant to be used for
we don't editorialize them much
Stephen Newman
@goodisontoffee
Oct 05 2017 14:08

Is there anyone out there that can help me get my head around the implications that leveraging persistence in an existing actor. I've changed the base class and am moving some "commands" over to the construct events, persist, process event pattern but am getting what "feels" like asynchronous processing of the event processing. Is it true to say that:

1) A message is received
2) Message is treated as a command and an event is created from the command
3) Persist is called supplying the event to persist and a handler to be invoked after successful persistence
4) Next message is pulled from the mailbox and processed
5) Persistence completes
6) Handler supplied in 3 is invoked with persisted event

That's how it feels, so I wonder if that is accurate, and is the fix to complete the moving over from messages to Commands/Events and it'll be okay.

Dave
@davenewza
Oct 05 2017 14:12
Question around async methods which return data (to an Ask) and PipeTo: would using ContinueWith on faulted tasks be a reasonable way to 'catch' and handle exceptions thrown. Example:
            Receive<SomeRequest>(request =>
            {
                GetSomethingAsync(request)
                    .ContinueWith(t => new FailedResponse(t.Exception), TaskContinuationOptions.OnlyOnFaulted)
                    .PipeTo(Sender);
            });
Dave
@davenewza
Oct 05 2017 14:20
if i try this, i get an empty Akka.Actor.Status.Failure message returned
Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:20
@davenewza ideally we should populate the exception into that Status.Failure message
part of the issue there though is that you'll never get anything on that PipeTo if the task succeeds normally I don't think
since PipeTo is continuing off of the OnlyOnFaulted Task
I have an example of what I usually do here...
// pipe the result of our markets to ourselves
            _exchangeFeedClient.HttpClient.Markets.GetProducts(cts.Token).ContinueWith<object>(tr =>
            {
                if (tr.IsCanceled || tr.IsFaulted)
                    return new Status.Failure(tr.Exception);
                return tr.Result;
            }).PipeTo(Self);
I have a catch-all continuation
that I use to handle any case
success or failure
and then my actor who receives this...
Receive<Status.Failure>(s =>
            {
                _currentRetryPolicy = _currentRetryPolicy.Retry(); // update the retry data
                _log.Warning(
                    "Request for list of exchange trade products timed out from {0}. Retrying in {1} seconds with {2} attempts remaining.",
                    _exchangeFeedClient.Endpoints.RestEndpointUri, _currentRetryPolicy.CurrentRetryInterval,
                    _currentRetryPolicy.RemainingAttempts);
                AcquireProductsFeed(_currentRetryPolicy.CurrentRetryInterval);
            }, failure => _currentRetryPolicy.CanRetry);

            Receive<Status.Failure>(s =>
            {
                _log.Error("ERROR: unable to contact exchange at {0} after {1} attempts. Aborting.",
                    _exchangeFeed.HttpClient.Endpoints.RestEndpointUri, _retryPolicyProvider.MaxNrOfAttempts);
                _currentRetryPolicy.Retry(); // throw a HopelessOperation exception on purpose
            }, failure => !_currentRetryPolicy.CanRetry);

            // Received data from the exchange API.
            Receive<ApiResult<IEnumerable<Product>>>(products =>
            {
                if (products.Status == HttpStatusCode.OK)
                {
                    _tradeProducts.AddRange(products.Result);
                    _log.Info("Received products from exchange: {0}", string.Join(",", _tradeProducts.Select(x => x.id)));
                    BecomePublishing();
                }
                else if (_currentRetryPolicy.CanRetry
                ) // something went wrong with our web request, but we have retry attempts remaining
                {
                    _currentRetryPolicy = _currentRetryPolicy.Retry(); // update the retry data
                    _log.Warning(
                        "Received error with our HTTP request ({0}): {1}. Retrying in {2} with {3} attempts left.",
                        products.Status, products.Message,
                        _currentRetryPolicy.CurrentRetryInterval, _currentRetryPolicy.RemainingAttempts);
                    AcquireProductsFeed(_currentRetryPolicy.CurrentRetryInterval);
                }
                else // web request failed, no retry attempts remaining
                {
                    _log.Error(
                        "ERROR: unable to contact exchange at {0} after {1} attempts. HTTP Status: {2}, Message: {3}. Aborting.",
                        _exchangeFeed.HttpClient.Endpoints.RestEndpointUri,
                        _retryPolicyProvider.MaxNrOfAttempts, products.Status, products.Message);
                    _currentRetryPolicy.Retry(); // throw a HopelessOperation exception on purpose
                }
            });
AcquireProductsFeed(_currentRetryPolicy.CurrentRetryInterval); causes me to re-run the task that failed
Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:26
and the _currentRetryPolicy thing is just a strategy class I wrote that implements various retry strategies
the implementation I'm using here is an exponential-backoff type approach
I wrote that stuff by hand but you can use a library like Polly to get that for free
@goodisontoffee if you call the normal Persist method
the actor will complete its persistence operation before the next message from the mailbox can be processed
if you call PersistAsync
it will behave as you've described
Dave
@davenewza
Oct 05 2017 14:28
@Aaronontheweb thank you. checking it out
Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:28
but even if you call multiple PersistAsync calls in a row
all of your events will still be persisted in order
because the journal itself is implemented as an actor
and it will receive the messages in its own mailbox in that order
Stephen Newman
@goodisontoffee
Oct 05 2017 14:30
Just Persist being called, I'll try to confirm but I can't share the code so I'll have to make something that also exhibits what I'm seeing. At which point the example will work properly ;)
So Persist blocks new message consumption until the persistence is complete.
Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:32
under the covers
the actor is just stashing messages until it gets an acknowledgement that the persist operation has completed
and then it invokes the callback
so it's not literally blocking a thread
Andrey Leskov
@andreyleskov
Oct 05 2017 14:58

Hi all, trying to build client to remote akka system using association. Using test:

public class AssociationErrorTest
    {
        public class EchoActor : ReceiveActor
        {
            public EchoActor(){Receive<object>(m => Sender.Tell(m));}
        }

        [Fact]
        public async Task Test_association()
        {
            var server = ActorSystem.Create("server", @"akka { actor.provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                                                               remote.dot-netty.tcp { port = 10001 
                                                                                      hostname = localhost}}");
            var serverActor = server.ActorOf<EchoActor>(nameof(EchoActor));
            var client = ActorSystem.Create("client", @"akka{ actor.provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
                                                                remote.dot-netty.tcp { port = 0
                                                                                       hostname = localhost}}");
            var remoteActorRef = await client.ActorSelection(@"akka.tcp://server@localhost:10001/user/EchoActor").ResolveOne(TimeSpan.FromSeconds(5));
            await remoteActorRef.Ask<string>("Hello");
        }
    }

if I run it as single test, all is OK . But if I run it with bunch of test, actor selection hangs. Got error from internals:

17-10-05 17:50:08.366 [DBG TH193] Src:[remoting
 "Associated [akka.tcp://server@localhost:10001] <- akka.tcp://client@localhost:5703"

17-10-05 17:50:08.375 [DBG TH201] Src:[endpointWriter#116268940]
 "Associated [akka.tcp://client@localhost:5703] -> akka.tcp://server@localhost:10001"

17-10-05 17:50:08.375 [DBG TH201] Src:[endpointWriter#116268940]
 Drained buffer with maxWriteCount: 50, fullBackoffCount: 1,smallBackoffCount: 0, noBackoffCount: 0,adaptiveBackoff: 1000

17-10-05 17:50:08.388 [DBG TH201] Src:[client)
 Resolve of path sequence [/"temp/N"] failed

looks like client system cannot locate temp actor during Ask()
Can anybody suggest reasons? May be I need some additional configuration ?

Aaron Stannard
@Aaronontheweb
Oct 05 2017 14:59
@andreyleskov dollars to donuts
issue is either going to be a static variable that is shared among the actor system instances and this test is running with AppDomains turned off
or one of the remote actor systems is replying to an actor who has since terminated
Andrey Leskov
@andreyleskov
Oct 05 2017 15:01
sounds reasonable, but in test above I don't use anything static
may be something inside akka system itself?
Aaron Stannard
@Aaronontheweb
Oct 05 2017 15:01
yeah that's what I meant
the name counter we use for naming temporary actors
might be one
Andrey Leskov
@andreyleskov
Oct 05 2017 15:01
ooh
you are right
I see letter for temp actor always increasing ))
ok, will run such tests in separate domains
Stijn Herreman
@stijnherreman
Oct 05 2017 15:02
I'm having trouble doing more than one transition in an FSM. Not sure if it's a problem with the FSM code or if it's a problem with the unit tests. Simple and full reproducible example at https://stackoverflow.com/questions/46588702/why-does-this-fsm-only-succeed-at-one-state-transition if anyone wants to take a look.
Andrey Leskov
@andreyleskov
Oct 05 2017 15:02
thank you a lot for blazing fast answer ! @Aaronontheweb
Stijn Herreman
@stijnherreman
Oct 05 2017 15:03
(Is it OK to ask for support here, by the way?)
Aaron Stannard
@Aaronontheweb
Oct 05 2017 15:07
@stijnherreman yep, good to ask but it's always good to use StackOverflow so other people can find the answer when they google later
I left an answer on the SO thread
but you need to add a handler for the Done state
otherwise that state is undefined by the FSM
Stijn Herreman
@stijnherreman
Oct 05 2017 15:11
@Aaronontheweb thanks! I was stuck on this for a couple of hours already, trying a bunch of different things.
Aaron Stannard
@Aaronontheweb
Oct 05 2017 15:12
did that suggestion work?
Stijn Herreman
@stijnherreman
Oct 05 2017 15:12
Yes, see the comment to your answer
Aaron Stannard
@Aaronontheweb
Oct 05 2017 15:13
ah nice
good deal, I'd been getting behind in racking up my SO karma
Stijn Herreman
@stijnherreman
Oct 05 2017 15:18
Heh :) on that topic, not that I have a shortage of rep but feel free to upvote the questions :)
Andrew Young
@ayoung
Oct 05 2017 22:43
@Danthar thanks. what about with the default wire format or hyperion?