We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Farabi Kurmanshady • 6 years ago

Thank you very much for this post! I'm a newbie to Akka.NET & .NET Core. I really appreciate your approach using of delegate to use IActorRef in Controller class. But I have a question now. What if I instantly need some IActorRef being assigned to delegate when the WebApp is up, not when the controller class is instantiated or called?

Havret • 6 years ago

Farabi Kurmanshady In order to initialize the actor eagerly you have to resolve the delegate on ApplicationStarted callback.


lifetime.ApplicationStarted.Register(() =>
{
app.ApplicationServices.GetService<actorsystem>(); // start Akka.NET
app.ApplicationServices.GetService<booksmanageractorprovider>(); // initialize your actor eagerly
});

Farabi Kurmanshady • 6 years ago

Thank you for your feedback!

Matt Lethargic • 5 years ago

From my readings around AKKA.Net it seems that this isn't the most ideal way of fronting an AKKA.Net system. Looks like the ideal system would have an AKKA cluster and then ASP.Net would talk to that cluster via remoting. Thoughts? Could you do an article on that?

Havret • 4 years ago

Matt Lethargic You are absolutely right. In a real-world application, you should definitely follow that direction. An article about Akka Clustering was something I had on my radar back in the days. Unfortunately, I haven't been using Akka on a daily basis for quite some time now. I cannot promise you an article on this topic, but I have a demo project that shows, how one could write this kind application. It's slightly outdated, but you should find there some useful patterns and practices I myself consider as very useful. It is the extended version of the example application from this article, so it should be easy for you to navigate there.

https://github.com/Havret/a...

R Adams • 6 years ago

Interesting article. Watched a few videos on Actors so trying to understand the paradigm and technology. From what I understood Actors should be very simple and follow a single responsibility principle. So should there not be three actors?, e.g. AddBookActor, FindBookByIdActor and GetBooksActor.

Jhonnatan Panoch • 5 years ago

Your question kinda made me understand better the responsibility principle. Thx

Havret • 6 years ago

R Adams Thank you very much for the feedback!

Actors should be simple and follow single responsibility principle but in the same way as aggregates in Domain Driven Design do. For the simplicity of this example, I keep a list of domain entities inside of a single actor. In real world application you should follow Child-Per-Entity pattern (https://petabridge.com/blog... - each entity should be represented by its own actor.

If there were three actors, e.g. AddBookActor, FindBookByIdActor and GetBooksActor you would miss the whole point of using Akka, because to work properly, these actors would have to share a common state.

I hope this answers your question.

Paul Van Bladel • 7 years ago

Very nice article.
Would your approach work when the actor itself has dependencies via it's constructor. So imagine your booksmanager actor needs access to a particular service or a DbContext.

Havret • 7 years ago

Paul Van Bladel Yesterday I added a blog post where I describe how you can deal with DbContext inside your Akka.NET application. --> https://havret.io/akka-enti...

Paul Van Bladel • 7 years ago

HI, thanks a lot for keeping me informed. Very nice article and useful !. Cheers

Havret • 7 years ago

Thank you very much for the feedback! I really appreciate it.

As for your question. If we assume that my BooksManagerActor has a dependency on ISomeService, it can be done as follows:

services.AddTransient<isomeservice, someservice="">();
services.AddSingleton<booksmanageractorprovider>(provider =>
{
var actorSystem = provider.GetService<actorsystem>();
var someService = provider.GetService<isomeservice>();
var booksManagerActor = actorSystem.ActorOf(Props.Create(() => new BooksManagerActor(someService)));
return () => booksManagerActor;
});

There is one point to make here. Due to the nature of actors which can (in theory) live forever, dependency ISomeService will live as long as our actor lives. In this particular case, it effectively becomes a singleton even though I registered it using the AddTransient method. While it is not a problem for ISomeService (which is a made up service which does nothing useful), it may be a dealbreaker for DbContext which by no means should live forever. Managing dependency lifetime is a delicate matter in Akka world, and it is a great topic for a blog post on its own.

Gustavo • 4 years ago

Havret in the case of having more than 1 api with multiple controllers, and all web api registering

services.AddSingleton(_ => ActorSystem.Create("bookstore", ConfigurationLoader.Load()));

Will this create multiple Actor System of bookstore system?

Havret • 4 years ago

@Gustavo It depends if all your controllers are hosted inside of a single ASP.NET Core app, then you would have a single bookstore actor system per app. If you have multiple apps, and you would like to share the Actor System throughout them, you should delve into the topic of Akka Clustering.

Gustavo • 4 years ago

@havret

Well yes I'm using several clusters, several api these api starts with an actor main router which eagerly starts other cluster routers. What I've noticing is these api seems to start the main router for each of them instead of one, the first to come up to start it.

So I'm wondering where the problem with the design lies or where can I change it to always have the main cluster router without starting multiple copies of it.

Havret • 4 years ago

I'm not sure if I understand you correctly. But if you are using clustering and really have multiple clusters, you should have one actor system per cluster.

Regarding the cluster router problem, as far as I remember, cluster router is built on top of cluster singleton. If your cluster is configured correctly you should only have ONE instance of such router.

Please check out this example --> https://github.com/Havret/a... and see how I am using `book-query-handler` via cluster router.

Irwan Azam Bin Ahmad • 6 years ago

Hai Havret , nice article, I've try using your delegate solution to handle the reference to Actor object, but it will not work if your Actor have WithRouter configuration eg: RoundRobinPool

Havret • 6 years ago

Irwan Azam Bin Ahmad
Hi, thanks for your comment. Could you please explain why would it not work in your case? I'm using it exactly that way in my current project. Not only with Routers but with Cluster Singletons and Cluster Sharding as well.

To utilize Router for BooksManagerActor from the code example, all you have to do is:

services.AddSingleton<booksmanageractorprovider>(provider =>
{
var actorSystem = provider.GetService<actorsystem>();
var booksManagerActor = actorSystem.ActorOf(Props.Create(() => new BooksManagerActor()).WithRouter(new RoundRobinPool(5)));
return () => booksManagerActor;
});

Irwan Azam Bin Ahmad • 6 years ago

For a testing, I just create simple BookManagerActor just to print Self.Path, so that i know the actual actor path that handle the message

public class BookManagerActor : ReceiveActor
{
public BookManagerActor()
{
Receive<string>(m =>
{
Console.WriteLine(Self.Path);
});
}
}

I expect the console should return something like this for RoundRobinPool(5):

akka://baku/user/$a/$a
akka://baku/user/$a/$b
akka://baku/user/$a/$c
akka://baku/user/$a/$d
akka://baku/user/$a/$e

and will return back to
akka://baku/user/$a/$a
...

but the result is different

akka://baku/user/$a$a
akka://baku/user/$b/$a
akka://baku/user/$c/$a
akka://baku/user/$d/$a
akka://baku/user/$e/$a
akka://baku/user/$f/$a
...
akka://baku/user/$j/$a

Havret • 6 years ago

Hey, you probably have your delegate registered with wrong lifetime settings. It should be registered as singleton. Otherwise DI container recreate your Router Actor every time you ask for it.

Here are the results I got:

https://uploads.disquscdn.c...

Irwan Azam Bin Ahmad • 6 years ago

Thanks!

Mladen Mihajlovic • 7 years ago

Nice article. Can you tell me which vscode extension that is?

Havret • 7 years ago

Thanks!

The extension I used to play with the API is REST Client. You can get it here --> https://marketplace.visuals...

Mladen Mihajlovic • 7 years ago

Man that's a great extension, thanks!