These are chat archives for akkadotnet/akka.net

1st
Feb 2016
Filip Kinský
@Buthrakaur
Feb 01 2016 07:51
Hello, I'm just beginning with Akka so forgive me my first dummy question, please :smile: I'm just little bit confused how "untyped" interaction beteen actors using IActorRef is. Let's take for example https://github.com/petabridge/akkadotnet-code-samples/blob/master/Cluster.WebCrawler/src/WebCrawler.Shared.IO/DownloadCoordinator.cs#L60 - DownloadCoordinator talks to DownloadsTracker and Commander, but they have exactly the same interface IActorRef even though each of them does something radically different and also supports very different messages. Is there any possibility how to narrow down the IActorRef dependency so as it could express the role of the actor? I mean something like using IHandle<TMessage> instead of IActorRef. It'd also make the testing more natural from standard .NET development point of view. This is something I'm really confused of at the moment and find it quite awful from the development and also unit testing perspective (what's so special about actors they can't be unit tested in standard way?!). I guess I only miss some point here and someone would kindly explain me my mistake - thanks in advance for this :smile:
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 08:14
@Buthrakaur you can create your own wrapper over the standard ActorOf implementation (like i.e. Akkling does) or use some library that abstracts messaging layer into async methods (like Akka.Interfaced), however that will probably hurt your performance.
when it comes to tests, could you describe your intent? I've found Akka TestKit way a pretty sane solution when compared to standard (messy) .NET tests. You create an actor, initialize it's state with series of input messages and validate it's behavior through series of output messages
Filip Kinský
@Buthrakaur
Feb 01 2016 08:37

@Horusiath thanks for your fast response - I'll take a look on those libraries. I find the dependency on IActorRef too weakly typed to sum up my complaints - it's like depending on object or dynamic instead of something like IShoppingCart. It's also about tightly coupling application logic to Akka.NET.

To the testing: I find standard mocking techniques for interaction between application components natural way for testing. Something like:

shoppingCart.Handle(new AddProduct("notebook"));

userActivityTracker.Received().Handle(Arg.Is<UserAction>(a => a.Name == "ProductAddedToCart" && a.Payload == "notebook"));
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 08:46
@Buthrakaur ability to tell any message to IActorRef is aligned with ability to switch actor behavior at runtime - which is a very powerful concept in statefull applications and makes things like Finite State Machines easy to implement.
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 08:52
when it comes to mocking - it's almost never necessary. Your example could be written as follows:
var shoppingCart = Sys.ActorOf(Props.Create(() => new ShoppingCart(activityTracker: TestActor)));
shoppingCart.Tell(new AddProduct("notebook"));

// assuming that UserAction is structuraly equatable
ExpectMsg(new UserAction("ProductAddedToCart", "notebook"));
Yin Zhang
@melcloud
Feb 01 2016 08:55
@Buthrakaur you tightly couple your application infrastructure to Akka.NET, but be flexible on business logic.
Filip Kinský
@Buthrakaur
Feb 01 2016 09:21

@Horusiath , @melcloud : thanks for your advice.

@melcloud what do you exactly mean by flexible on business logic? Extract business logic from actors and make them manage just the communication between system components? I can't imagine how to achieve this without direct interaction between the application services, which shouldn't know about actor system. Do you have any example, please?

Bartosz Sypytkowski
@Horusiath
Feb 01 2016 09:54
@tintoy what you were talking about, is the ability to have multiple log messages grouped by single correlation id into one logical context, right?
Adam Friedman
@tintoy
Feb 01 2016 09:55
@Horusiath hi - yep, more or less; I get that some activities are started by "non-public actors" but in general
if there are hundreds of actors all talking to each other
It would be super-useful to be able to trace the causality of a message
(A sent x to B, which resulted in y and z to C)
I suspect for something like Akka with all the independent actors doing their own thing it's not as simple as, say, a user-initiated operation
but would probably still be high-value
for example
in most of our products at the moment
we have an activity Id that hops across tiers (regardless of whether you're using WebAPI, WCF, or just vanilla ASP.NET / Ajax) even down to metadata in some databases
and across service bus queues
if a user reports an error and can include the activity Id
we can track down the exact set of circumstances that led to their problem
(well, on a good day :smile: )
I'm using Akka to rebuild our provisioning engine (something it's great fit for)
but my solution to continuing the user's logical activity to provision a user (or whatever) feels a little clumsy / bolted-on
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 09:59
this reminds me of Twitter's Zipkin
Adam Friedman
@tintoy
Feb 01 2016 10:00
Ah
yes, I saw something about that at a conference recently
it does have some appeal
at this stage, the main issue is that Akka's design doesn't really make room for out-of-band / ambient data to travel with messages
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:01
but maybe you shouldn't rely on logging, instead building your own actor tracing around event bus or distributed pub/sub?
Adam Friedman
@tintoy
Feb 01 2016 10:01
It's not a simple problem to solve, I suspect
Sure, we can definitely do that
but there's a lot of value in being able to correlate events across multiple subsystems
for example, if I have (for example) an actor that acts as a client proxy for a web API
tracing a message from another actor (say a dispatcher) to one of the proxies behind a pool router
and then across the wire to the web API
means I have multiple layers of telemetry I can drill down into when things don't behave as expected
We currently use ETW and Microsoft's semantic logging service both feeding into Seq
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:03
yes, I agree with that. Just saying, that it's easier to use existing tools to implement something like that that fits your needs
Adam Friedman
@tintoy
Feb 01 2016 10:03
for sure
So we have quite a lot of tooling around instrumentation and telemetry
and for most frameworks
have had to write only tiny hooks to get useful information out
at this stage I'm just trying to find that magic point of diminishing returns for Akka
so I can work out what's worth spending effort on
and what isn't
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:04
well you have also Akka.Cluster.Monitoring
Adam Friedman
@tintoy
Feb 01 2016 10:05
Hmm
I haven't looked at that
I'll have a look over to see how it works
(the other side of this is that because we do have a fair bit of ops tooling, including management packs for SCOM, I wouldn't want to add too many more telemetry formats into the mix)
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:06
I've used it in my previous work to bind my actors events (from lifecycle to business) to ETW engine
Adam Friedman
@tintoy
Feb 01 2016 10:06
Interesting
I don't see it directly in the core repo
is it under contrib?
Adam Friedman
@tintoy
Feb 01 2016 10:08
ah, cheers!
nifty
how about Context.CreateLogger BTW?
does that seem like something that could be inherited from / overridable some day?
(so still raise those events to the bus but might add more data to messages that specific loggers might know how to process)
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:09
I think, it was mentioned clearly for something like 4 basic log events, not any more full-blown metric/tracing system
Adam Friedman
@tintoy
Feb 01 2016 10:09
Hmm
I'm not really suggesting anything more than those 4 events
just additional "out-of-band information" in them
but no biggie
Yin Zhang
@melcloud
Feb 01 2016 10:10
@Buthrakaur Yes. I mean that. I think actor as work flow control, and extract business logic to domain model and application service. For application service, they can be passed in as dependencies.
public class BankAccount
{
    private decimal _balance;

    public BankAccount(decimal initialDeposit)
    {
        _balance = initialBalance;
    }

    public void Deposit(decimal amount)
    {
        _balance += amount;
    }
}

public class BankAccountActor : ReceiveActor
{
    private BankAccount _bankAccount;

    public BankAccountActor()
    {
        Ready();
    }

    private void Ready()
    {
        Receive<OpenAccount>(msg => {
            _bankAccount = new BankAccount(msg.InitialDeposit);

            Sender.Tell(new AccountOpened(_bankAccount));
        });

        Receive<Deposit>(msg => {
            _bankAccount.Deposit(msg.Amount);

            Sender.Tell(new BalanceUpdated(_bankAccount.Balance));
        });
    }
}
Adam Friedman
@tintoy
Feb 01 2016 10:11
I can always just use my custom base classes that set up / remove the ambient information needed by my actors' "user" code
Maybe I'll work up an example and post it to the issue so we have something concrete to talk bout
even if you guys don't find it useful (totally fine of course) it may still wind up being helpful to someone else someday
Zetanova
@Zetanova
Feb 01 2016 10:27
@tintoy Yes, i am using the ActivityId too with WCT, WebAPI, EF and even email. But my name for it is OperationId. This value is a context value and should normaly go over as ambient/head property. I thought about it for akka too, what i know the didnt plan for it. The ActorDispatcher of course dont support the callcontext (and shouldn't) and to but the OperationId into the message would be as to write it in the Email-Body over the title. To Warp the message that a base-actor class can unwarp it, would be with serialzion bad. The only think what would make sends is to infent a batch message or a batch-message-id that the reeiver mailbox garanties to but in sequence into the mailbox, without only foreign messages in between. Then it would be possible to send the contextmessage that includes the OperationId in front of one or many other messages and the receiver could use the first message to setup the callcontext to handle the rest of the batched-messages
Adam Friedman
@tintoy
Feb 01 2016 10:34
@Zetanova We just have a base message class that captures ambient activity Id when first constructed and a base class for actors that restores it in AroundReceive
Zetanova
@Zetanova
Feb 01 2016 10:34
And internaly an envelope is used ... i think there is the right possition to copy the OperationId over to new message handlers
Adam Friedman
@tintoy
Feb 01 2016 10:34
will post code when I get time
Zetanova
@Zetanova
Feb 01 2016 10:35
yes
"base"
if u would need two or u need to use a 3th message, the abient value is lost
Adam Friedman
@tintoy
Feb 01 2016 10:37
Actually no - for us it doesn't
we set and restore the ambient activity Id in AroundReceive
so any messages constructed by that actor in AroundReceive
will work correctly
sorry in Receive
Zetanova
@Zetanova
Feb 01 2016 10:38
?
Adam Friedman
@tintoy
Feb 01 2016 10:38
lemme dig up some code
Filip Kinský
@Buthrakaur
Feb 01 2016 10:38
@melcloud thanks for clarification.
Zetanova
@Zetanova
Feb 01 2016 10:39
yes, and u are using a spezial message base class for all communication?
Adam Friedman
@tintoy
Feb 01 2016 10:39
yep
/// <summary>
        ///        Called before the actor's <see cref="Receive"/> implementation processes a message.
        /// </summary>
        /// <param name="receive">
        ///        The actor's <see cref="Receive"/> implementation.
        /// </param>
        /// <param name="message">
        ///        The message being received.
        /// </param>
        /// <returns>
        ///        <c>true</c>, if the message was handled by the actor; otherwise, <c>false</c>.
        /// </returns>
        protected override bool AroundReceive(Receive receive, object message)
        {
            IPropagateLogicalActivity logicalActivity = message as IPropagateLogicalActivity;

            Guid? activityId = logicalActivity?.LogicalActivityId;

            using (ApertureCorrelationManager.BeginActivityScope(activityId))
            {
                return base.AroundReceive(receive, message);
            }
        }
and
Zetanova
@Zetanova
Feb 01 2016 10:39
yes
Adam Friedman
@tintoy
Feb 01 2016 10:39
/// <summary>
    ///        The base class for inter-actor messages with an activity correlation Id.
    /// </summary>
    public abstract class MessageBase
        : IPropagateLogicalActivity
    {
        /// <summary>
        ///        Create a new message using the ambient activity.
        /// </summary>
        protected MessageBase()
            : this(ApertureCorrelationManager.GetCurrentActivityId())
        {
        }

        /// <summary>
        ///        Create a new message using the specified activity Id.
        /// </summary>
        /// <param name="activityId">
        ///        The activity correlation Id.
        /// </param>
        protected MessageBase(Guid? activityId)
        {
            ActivityId = activityId;
        }

        /// <summary>
        ///        The activity correlation Id used track the logical activity represented by the message.
        /// </summary>
        public Guid? ActivityId
        {
            get;
            private set;
        }

        /// <summary>
        ///        The logical activity identifier (if known).
        /// </summary>
        Guid? IPropagateLogicalActivity.LogicalActivityId => ActivityId;

        /// <summary>
        ///        Modify the message to use the current ambient activity Id.
        /// </summary>
        /// <typeparam name="TMessage">
        ///        The type of message to modify.
        /// </typeparam>
        /// <param name="message">
        ///        The message to modify.
        /// </param>
        /// <returns>
        ///        The message (enables inline use).
        /// </returns>
        public static TMessage CaptureCurrentActivityId<TMessage>(TMessage message)
            where TMessage : MessageBase
        {
            message.ActivityId = ApertureCorrelationManager.GetCurrentActivityId();

            return message;
        }
    }
oops, sorry, gotta run
will check back here for messages tomorrow
:)
Zetanova
@Zetanova
Feb 01 2016 10:41
it's implies that all messages have this base class
Arjen Smits
@Danthar
Feb 01 2016 10:41
@Horusiath Is the sqllite plugin for persistence safe for use with 1.0.6 ? There where some updates to the sqlserver variant. Not sure if those bugfixes should be applied to the sqllite version as well. (i would expect it should, hence my question).
Zetanova
@Zetanova
Feb 01 2016 10:41
even if u get something like "Success" or Terminated the ambient value is lost
the same think inside the envelope would be a hit
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:43
@Danthar AFAIK those bugfixes concerned Akka.Persistence as a whole, not a single provider
Arjen Smits
@Danthar
Feb 01 2016 10:45
oh. Cause sqllite hasn't been updated since 13-aug. Doesn't seem its up to date for 1.0.6 then (?)
Arjen Smits
@Danthar
Feb 01 2016 10:47
Ah the nugets. I was talking about the repo.
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:48
Are you talking about this repo? - it should be deleted :)
Arjen Smits
@Danthar
Feb 01 2016 10:48
yes. Ah that explains it
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:49
sqlite is used as default inside akka core
Arjen Smits
@Danthar
Feb 01 2016 10:49
aah that makes sense.
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:49
to make Akka.Persistence.Sql.Common reachable and testable inside the same repo
Arjen Smits
@Danthar
Feb 01 2016 10:50
Yeah i want to use a persistent actor with local disk storage so sqllite seemed like a good fit. Didn't knew it was the default provider
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 10:50
no no. It's not set as default
Arjen Smits
@Danthar
Feb 01 2016 10:51
myeah. I use the wrong word. But we both mean the same thing.
*meant
Anthony Brown
@bruinbrown
Feb 01 2016 11:37
@tintoy there was a blog post on the Let It Crash site explaining how you can manage this tracing in Akka on the JVM but it can likely be adapted for Akka.Net http://letitcrash.com/post/30585282971/discovering-message-flows-in-actor-systems-with
Adam Friedman
@tintoy
Feb 01 2016 11:41
Ooh, nice find! Thanks that's going right to the top of my reading list.
EGirardi
@EGirardi
Feb 01 2016 16:24
Hello All - I am new to Akka.net and I have a question. Is there a "Best Practice" for implementing an HTTP server to take in requests (i.e. roll your own via a HTTP Listener in C#) or does Akka.Net provide that for you already ?
Anthony Brown
@bruinbrown
Feb 01 2016 16:51
@EGirardi There's no built in HTTP server for Akka.Net just yet, that comes in the form of Akka-Http which depends on Akka-Streams I believe which haven't been ported. You could roll your own if you wanted to using HTTP listener or you can use any of the .Net HTTP servers currently available, whether it's MVC, Nancy, ServiceStack, Suave, Freya etc and just call into your actor system using Ask, like in this blog post https://petabridge.com/blog/akkadotnet-aspnet/
@EGirardi Or if you're able to use raw TCP, UDP or even websockets etc, then Akka.IO might also be an option for you
Aaron Stannard
@Aaronontheweb
Feb 01 2016 17:00
@Horusiath deleted Akka.Persistence.Sqllite since it's part of the main repo
oversight on my part
Aaron Stannard
@Aaronontheweb
Feb 01 2016 17:06
@EGirardi @bruinbrown I'd like to see us do a version of Akka.HTTP that is essentially just "automatically generate HTTP routes to all actors using WebAPI or NancyFX"
no need to write an entire HTTP server from scratch if we can avoid it - that's something that .NET actually does much better than the JVM IMHO
Aaron Stannard
@Aaronontheweb
Feb 01 2016 17:15
@bruinbrown I'm going to make the DotNetty transport also use the helios settings
like I'll deprecate the Helios section and replace it with a DotNetty one going forward
but I won't break compatibility with it outright if possible
Anthony Brown
@bruinbrown
Feb 01 2016 17:57
@Aaronontheweb awesome cheers, just writing the section on remoting at the minute so was making sure I wouldn't have to change that a couple of months down the line
Troy
@bbqchickenrobot
Feb 01 2016 18:15
Hey guys - had a question that I can't seem to find much on.....
What'st he diff between akka.net and a message bux. i.e. - MassTransit?
Meaning I'm setting up a webapi client to pass work to another set of distributed game servers that will process the work and then return data to the WebApi once done. I think Akka.net would be great for this....
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:23
@bbqchickenrobot think of Akka.NET like a superset of what RabbitMQ can do
RabbitMQ / MassTransit is designed primarily for propagating messages between services using a transport, different types of communication strategies (like pub/sub,) and configurable durability
Akka.NET can do that, but it's also used at the application layer for the stuff that produces and consumes those messages
gives you the ability to design your entire application stack using event-driven architectures
which is really helpful for lots of applications like analytics, IoT, gaming, ecommerce (marketing automation / personalization / dynamic pricing)
lots of our users use both a message queue technology AND Akka.NET
usually because they were already using a message queue for some part of their infrastructure and it "just works"
but they'll rewrite the consumers of that message queue to use Akka.NET actors so it becomes easier to concurrently and asynchronously process those messages without writing lots of boilerplate code
you can ask @stefansedich or @annymsMthd about that - they've both used Akka.NET + Rabbit simultaneously in their production apps IIRC
David Sinclair
@dsincl12
Feb 01 2016 18:27
stupid question, is Akka.NET compatible with Akka, i.e could I use Scala with Akka somewhere?
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:28
@dsincl12 not a stupid question - it's coming up really often now actually
the short answer is "not by default"
but it can be made possible - you'd need to have some sort of common object + wire format
David Sinclair
@dsincl12
Feb 01 2016 18:28
ah ok like a "bridge"
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:28
if you defined all of your Akka.NET --> Akka messages using something like Google Protocol Buffers
David Sinclair
@dsincl12
Feb 01 2016 18:29
ok got it
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:29
which would define identical .NET / Java objects + a shared wire format by default
you could make that work - you'd probably also have to register a custom serializer for those "shared" messages and load that via configuration too
that would be how I would do it
David Sinclair
@dsincl12
Feb 01 2016 18:30
ok, because right now i have all my "monitoring nodes" running as windows services on different boxes aroudn the world. thing is linux vps is a lot cheaper, i was thinking of using ZMQ for communication but felt that there must exist a better way to do this
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:33
@dsincl12 .NET Core can not come fast enough man
David Sinclair
@dsincl12
Feb 01 2016 18:33
amen to that
:)
Aaron Stannard
@Aaronontheweb
Feb 01 2016 18:34
:+1:
John Nicholas
@MrTortoise
Feb 01 2016 20:12
im working on protobuf and akka atm.
im having a dilema though over service decisions ... use web sockets? host something in wcf and use tcp bindings? trying to think of sane options
sensible frame for protobuf payload
Kamil Wojciechowski
@aph5nt
Feb 01 2016 20:25
when I use remoting, is it possible to spawn a persitent view on a different machine than its persistent actor ?
can I have n instances of the same view o a different machines ?
the general idea is to have one backend server and many clients with the views
@Aaronontheweb @Horusiath ??
Troy
@bbqchickenrobot
Feb 01 2016 20:28
coool, thx @Aaronontheweb !! Helpful, will leave out masstransit for this new endeavor
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 20:54
@aph5nt it is possible as long as persistent backend stays visible to all concerned parties
Roger Johansson
@rogeralsing
Feb 01 2016 21:14
@Horusiath as in, the database needs to be reachable from the remote view?
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 21:17
it needs to be reachable from the node, view lives in
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:22
im asking because,I have all actors under single webapp. now its time to scale, and I want to divide system into few parts. I will have the 'server' part and many isntance of webapps. each webapp can be created on demand by windows azure, when the webtraffic will be high.
the easy way would be to point all webpages to query the server (read from view)
but also server will have to know about all signalrActors
so as I understand each signalRactor will have to register somehow on the servers eventbus ??
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 21:30
@aph5nt maybe describe us the complete use case?
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:30
ok, give me a moment
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:42

case " Query the game state and send notifications to the UI "
current solution
got:

  • game actor that does some business logic (write)
  • game view that is being used for querying the game state (asp.net controller asks for state)
  • signalRActor that subscribes to the eventbus for given events and sends notifications to the UI

current performance:
with large VM on windows azure I can handle 1500 page requests per second (checked with blitz app)
(each requests == 3 queries to the game view)

problem:
the webtrafic can increase in the future and I want to be ready for that. Current solution
is placed in a single webapp, so can not use azure load balancer, because that would duplicate the systems.

My idea to solve the problem:

  • move game actor to a seperate cloud service
  • move game view and signalRActor to the webapp

connect the web and server actors with remoting
In case of new webapp created,
the signalRActor should subscribe remotly to the game actor events
and the game view should restore

Bartosz Sypytkowski
@Horusiath
Feb 01 2016 21:50
how game actor works?
does it represent some game session/room?
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:51
no its a single thing
no rooms
no sessions
it receives bets
and selects the winners after 1hour
nothing fancy there
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 21:52
so it can represent a single bet?
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:53
no, its a list of games, each game has many bets, after 24hours the old bets are removed
sory, old games are removed with bets
so it has 27 games with bets (3 current games and 24 previous ones)
Bartosz Sypytkowski
@Horusiath
Feb 01 2016 21:54
When designing actor systems, good practice is to search for natural boundaries of your domain and use them for partition your work into specific actors
(I meant single game before)
Kamil Wojciechowski
@aph5nt
Feb 01 2016 21:55
at the beginning i wantet to have one game actor per hour/game
but it was to difficult to sync everything for me... now this app would be designed in a different way
but
it works and its damn fast