Tag Archives: Akka .NET

Child Per Entity Pattern in Akka .NET

In Akka .NET, actors are very lightweight, and you’re encouraged to use lots of them. It’s thus very common to have a type of entity (e.g. stock symbol, event, session, etc), and an actor dedicated to each instance of that entity.

The source code for this article is available at the Gigi Labs BitBucket Repository. The project is called Entity Per Child (instead of Child Per Entity), because somehow it stuck in my head that way!

Let’s take a practical example. You have an application which receives updates for various different stocks listed on the stock exchange; each of these is represented by a symbol (e.g. MSFT represents Microsoft):

    public class StockUpdate
    {
        public string Symbol { get; }
        public decimal Price { get; }

        public StockUpdate(string symbol, decimal price)
        {
            this.Symbol = symbol;
            this.Price = price;
        }
    }

Updates are sent to a StockCoordinatorActor (for this example we’ll simulate this by just having the ActorSystem itself send these messages):

            using (var actorSystem = ActorSystem.Create("StockActorSystem"))
            {
                var props = Props.Create<StockCoordinatorActor>();
                var coord = actorSystem.ActorOf(props, "StockCoordinatorActor");

                coord.Tell(new StockUpdate("ABC", 1.20m));
                coord.Tell(new StockUpdate("XYZ", 0.59m));
                coord.Tell(new StockUpdate("ABC", 1.21m));
                coord.Tell(new StockUpdate("HBZ", 0.86m));
                coord.Tell(new StockUpdate("FUK", 1.20m));
                coord.Tell(new StockUpdate("XYZ", 0.57m));

                Console.ReadLine();
            }

Now, the StockCoordinatorActor will be responsible for spawning a child actor for each symbol, and directing messages concerning that symbol to that child actor. I see a lot of questions about how to store this mapping in a dictionary, but actually, you don’t need to. Actors can easily access information about their children, so you should use that to your advantage:

    public class StockCoordinatorActor : ReceiveActor
    {
        public StockCoordinatorActor()
        {
            this.Receive<StockUpdate>(Handle, null);
        }

        private void Handle(StockUpdate update)
        {
            var childName = update.Symbol;

            // check if a child with that name exists
            var child = Context.Child(childName);

            // if it doesn't exist, create it
            if (child == ActorRefs.Nobody)
            {
                var props = Props.Create(() => new StockActor(childName));
                child = Context.ActorOf(props, childName);
            }

            // forward the message to the child actor
            child.Tell(update.Price);
        }
    }

The child actor that handles the message will simply write out the price update in this example:

    public class StockActor : ReceiveActor
    {
        private string symbol;

        public StockActor(string symbol)
        {
            this.symbol = symbol;

            this.Receive<decimal>(Handle, null);
        }

        private void Handle(decimal price)
        {
            Console.WriteLine($"{Context.Self.Path} - {this.symbol}: {price} ");
        }
    }

Let’s run this:

akkanet-child-per-entity

I’m writing out the path of the actor that handles the update, to show that these are actually children of the StockCoordinatorActor.

If you’re dealing with a large number of actors, you might want to use a ReceiveTimeout to kill off the child actors after they’ve been idle for a period of time, to keep memory usage within reason. If a new message eventually comes in, the actor will be recreated by the same child creation logic.

This approach is called the Child Per Entity pattern. It’s actually very similar to using a consistent hashing router to assign work to a pool of dedicated actors based on an ID. With Child Per Entity, you have exactly one actor per ID, while with consistent hashing, you get actors handling multiple IDs. Due to the need to map this level of indirection, Child Per Entity is simpler to use for stateful actors.

On Akka .NET Actor Creation

Abstract: this article is a bit of a rant about how actors are created in Akka .NET, and suggests a way of making it just a little bit more manageable. This is written based on my limited knowledge of Akka .NET, and I will be more than happy to stand corrected on the matters I write about.

Actors Need Props

Creating an ActorSystem and actors in Akka .NET is one of the most basic necessities, and it is something you’ll be doing all the time. Once you have an ActorSystem, you can create actors using an IActorRefFactory implementation (i.e. the ActorSystem itself, or an actor’s Context). This requires you to use Props.

            using (var actorSystem = ActorSystem.Create("MyActorSystem"))
            {
                var props = Props.Create<MyActor>();
                var actor = actorSystem.ActorOf(props);

                Console.ReadLine();
            }

What the hell are Props?

This is explained by Unit 1 Lesson 3 of the Petabridge Akka .NET Bootcamp. Basically, the answer is something like: it’s a recipe for creating actors, but don’t worry about it for now; we’ll use it later.

As a matter of fact, it’s needed mainly for advanced scenarios such as remote deployment and clustering. Most of the time as you’re learning to use Akka .NET, you don’t really care about them.

Creating Props

There are three ways to create Props, all involving some manner of a call to Props.Create().

The first way is to give it a Type.

var props = Props.Create(typeof(MyActor));

This is discouraged by Akka .NET, because it has no type safety and in fact lets you do stupid things like this:

akka-actorcreaton-typeof

The second way is to use a generic form:

var props = Props.Create<MyActor>();

While this is encouraged in the bootcamp, I personally discourage this. This is because while it gives you type safety over the actor type, it doesn’t give you any guarantees with the parameters:

akkanet-props-generic-2

The third way is to pass in a factory method. This is a great way to create Props because it’s the only one that lets you pass dependencies into the actor’s constructor in a type-safe manner (particularly important to use constructor injection if you’re thinking of writing tests against your actors).

var props = Props.Create(() => new MyActor());

Making It Better

In reality, most of the time I don’t care about Props. So why do I have to constantly bother about them? Actually, if we take a closer look at the third way of creating Props, we can wrap them into oblivion:

akkanet-props-expression

See that generic Expression over there? That’s what we need to avoid all this madness. Based on that, we can create a generic method to take care of everything:

    public static class IActorRefFactoryExtensionscs
    {
        /// <summary>
        /// Creates an actor, creating props based on the provided
        /// actor factory method.
        /// </summary>
        /// <typeparam name="T">The actor type.</typeparam>
        /// <param name="actorRefFactory">ActorSystem or actor Context.</param>
        /// <param name="actorFactory">Actor factory method.</param>
        public static IActorRef CreateActor<T>(this IActorRefFactory actorRefFactory,
            Expression<Func<T>> actorFactory) where T : ActorBase
        {
            var props = Props.Create(actorFactory);
            var actor = actorRefFactory.ActorOf(props);
            return actor;
        }
    }

To create an actor directly from the ActorSystem, we now only need to do this:

var actor = actorSystem.CreateActor(() => new MyActor());

…and to do it from inside an actor, it’s just as easy:

var actor = Context.CreateActor(() => new MyActor());

Weird Conventions

This is where the rant begins.

Apart from all the weirdness associated with having to deal with Props in the first place, Unit 1 Lesson 3 of the Petabridge Akka .NET Bootcamp has this little gem that makes my day brighter every time I read it:

How do I make Props?

“Before we tell you how to make Props, let me tell you what NOT to do.

DO NOT TRY TO MAKE PROPS BY CALLING new Props(...). Similar to trying to make an actor by calling new MyActorClass(), this is fighting the framework and not letting Akka’s ActorSystem do its work under the hood to provide safe guarantees about actor restarts and lifecycle management.”

Here’s a similar gem from Unit 1 Lesson 1:

NOTE: When creating Props, ActorSystem, or ActorRef you will very rarely see the new keyword. These objects must be created through the factory methods built into Akka.NET. If you’re using new you might be making a mistake.”

Wait, what? These guys are telling us to call static Create() methods rather than using constructors. These are the same people who told us that using async/await in actors is bad (which has since been corrected). I don’t know, but I bet if you ask anyone who has done OOP before, they’ll tell you that if there’s a mistake, it’s in Akka .NET’s design.

But to really top it all, check out the following comment from Aaron Standard (Petabridge CTO and Akka .NET co-founder) on the Reddit thread about one of his articles (emphasis mine):

Orleans is a piss-poor implementation of the Actor model and breaks a lot of the conventions that make it powerful, aside from having an overall hideous set of programming conventions. But because MSFT released it, people will flock to it like lemmings.

“We’re going to keep working on Akka.NET because there’s a community supporting it now and because we believe in TypeSafe’s vision for actor systems.”

A case of the pot calling the kettle black? Or quoting Confucius, “Don’t complain about the snow on your neighbor’s roof when your own doorstep is unclean.”

In any case, my goal is not to start a flame war but to understand why the Akka .NET API (and codebase) is such a mess. If you look at the source code for ActorSystem, for instance, it does not do anything so particularly complicated that would justify banning constructor calls. In fact, the call to ActorSystem.Create() ends up here:

        private static ActorSystem CreateAndStartSystem(string name, Config withFallback)
        {
            var system = new ActorSystemImpl(name, withFallback);
            system.Start();
            return system;
        }

In fact, although you shouldn’t do this, this code works just as well as what we had before:

            using (var actorSystem = new ActorSystemImpl("MyActorSystem"))
            {
                actorSystem.Start();

                var actor = actorSystem.CreateActor(() => new MyActor());

                Console.ReadLine();
            }

Why is this even public such that I can call it?

Conclusion

The API provided by Akka .NET, particular in ActorSystem and actor creation, is very strange indeed. We are discouraged to do something as trivial a calling a constructor, and have to deal with Props even though we won’t need them most of the time. It is hard to speculate on why this API was written this way without having the developers provide insight on it.

At the very least, aside from pointing out these obvious flaws, this article aims to suggest best practices on how to go about creating Props, and to provide an extension method to hide the existence of Props for the majority of cases where using them directly isn’t really necessary.

Using ReceiveTimeout in Akka .NET

In Akka .NET, you can opt to receive a special message when an actor is idle (i.e. does not receive any message) for a certain period of time. This message is the ReceiveTimeout, and is particularly useful to clean up idle actors when using the Entity Per Child pattern (although various other scenarios exist where this might be used).

The source code for this article is available at the Gigi Labs BitBucket repository.

Let’s consider an ActorSystem with a single actor. The ActorSystem sends a message to this actor every few seconds, using the built-in Akka .NET Scheduler:

            using (var actorSystem = ActorSystem.Create("MyActorSystem"))
            {
                var actor = actorSystem.ActorOf(
                    Props.Create<SomeActor>(), "SomeActor");

                actorSystem.Scheduler.ScheduleTellRepeatedly(
                    initialDelay: TimeSpan.FromSeconds(1),
                    interval: TimeSpan.FromSeconds(5),
                    receiver: actor,
                    message: "Hello!",
                    sender: ActorRefs.NoSender
                );

                Console.ReadLine();
            }

In the actor itself, we call SetReceiveTimeout() in order to be able to receive a ReceiveTimeout message after the specified idle period elapses. Then, we handle the ReceiveTimeout message just like we would handle any other message.

    public class SomeActor : ReceiveActor
    {
        public SomeActor()
        {
            this.Receive<string>(Handle, null);
            this.Receive<ReceiveTimeout>(Handle, null);

            var timeout = TimeSpan.FromSeconds(3);
            this.SetReceiveTimeout(timeout);
        }

        private void Handle(string msg)
        {
            Console.WriteLine(msg);
        }

        private void Handle(ReceiveTimeout msg)
        {
            Console.WriteLine("Timeout received!");
        }
    }

If we run the application with the code we have so far, we get this:

akkanet-receivetimeout-nokill

Although we are handling the ReceiveTimeout message, we aren’t really doing anything to react to it. As the ReceiveTimeout documentation states, the ReceiveTimeout will keep firing after periods of inactivity.

To disable the ReceiveTimeout altogether, just call SetReceiveTimeout() again, passing in null:

this.SetReceiveTimeout(timeout);

You will often want to kill the actor altogether. In particular when using the Entity Per Child pattern, you will want to kill off actors that aren’t in use to keep your memory footprint low; and since you’ll have a parent actor taking care of routing messages and creating child actors as needed, any new message to that actor will cause it to be recreated.

There are different ways to kill an actor, so just pick one and use it in your ReceiveTimeout handler:

        private void Handle(ReceiveTimeout msg)
        {
            Console.WriteLine("Timeout received!");

            Context.Stop(Context.Self); // stop the actor
        }

Since we’re killing the actor now, any subsequent messages become undeliverable:

akkanet-receivetimeout-kill

Custom Loggers in Akka .NET

Akka .NET supports a flexible logging mechanism that can adapt with various logging providers, as we have seen in my earlier article on logging with Akka .NET. Aside from the default logger that writes to the console, you can plug in various loggers of your own choosing (e.g. NLog), set them up in configuration, and work with them using a common interface.

Sometimes, you may have specific logging requirements that are not covered by any of the existing logging plugins for Akka .NET. In such cases, you would need to write your own custom logger. Unfortunately, the Akka .NET Logging documentation does not explain how to do this at the time of writing this article.

This article is intended to fill this gap, explaining how to write a custom logger for Akka .NET, but also touching upon various topics such as reading custom configuration, actor lifecycle hooks, and cleanup of resources used by the ActorSystem. The source code for this article is available at the Gigi Labs BitBucket repository.

In a Nutshell

Akka .NET Logging is basically a port of Akka logging. Any logger is an actor that receives the following messages: Debug, Info, Warning, Error and InitializeLogger. These are all standard Akka .NET messages, and we will see how to use them in a minute. At the time of writing this article, I’ve come across the following loggers that one can refer to in order to see how custom loggers are built:

Main Program

For the sake of this article, we can go along with the following simple program:

            using (var actorSystem = ActorSystem.Create("MyActorSystem"))
            {
                var logger = Logging.GetLogger(actorSystem, actorSystem, null);
                logger.Info("ActorSystem created!");

                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
            }

In my earlier Akka .NET logging article, we had done logging only from within actors. The above code shows how you can use the same configured logger directly from the ActorSystem.

We are now going to need a little configuration.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <configSections>

<section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
  </configSections>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>

  <akka>
    <hocon>
      <![CDATA[ akka { loglevel = DEBUG loggers = ["AkkaNetCustomLogger.Loggers.ConsoleLogger, AkkaNetCustomLogger"] actor { debug { receive = on # log any received message autoreceive = on # log automatically received messages, e.g. PoisonPill lifecycle = on # log actor lifecycle changes event-stream = on # log subscription changes for Akka.NET event stream unhandled = on # log unhandled messages sent to actors } } } ]]>
    </hocon>
  </akka>

</configuration>

Here, we’re turning on all internal Akka .NET logging so that we can automatically get some logging output.

The important thing here is the loggers configuration, where we’re specifying the custom logger that we want Akka .NET to use. This is exactly how we had set up Akka .NET to use NLog in my earlier article, but this time we’re going to use a class called ConsoleLogger (which we have yet to create).

Writing the ConsoleLogger

As I mentioned earlier, any custom logger needs to handle five messages: Debug, Info, Warning, Error, and InitializeLogger. That’s the first thing we’ll set up our ConsoleLogger to do.

    public class ConsoleLogger : ReceiveActor
    {
        public ConsoleLogger()
        {
            Receive<Debug>(e => this.Log(LogLevel.DebugLevel, e.ToString()));
            Receive<Info>(e => this.Log(LogLevel.InfoLevel, e.ToString()));
            Receive<Warning>(e => this.Log(LogLevel.WarningLevel, e.ToString()));
            Receive<Error>(e => this.Log(LogLevel.ErrorLevel, e.ToString()));
            Receive<InitializeLogger>(_ => this.Init(Sender));
        }

        // ...
    }

The actual logging messages will use a common Log() helper method, since they differ only in log level (the operation of writing to the log destination is the same for all). Note that when we convert each of these classes to string, that includes the log level, so we don’t need to write it separately. In the case of the ConsoleLogger, we are passing in the LogLevel merely so we can use a different colour for each level.

The special message we haven’t covered yet is InitializeLogger. When the ActorSystem creates the logger actor, the internal event bus needs to know whether the logger is ready to start accepting messages. It does this by sending the logger actor an InitializeLogger message, and expects a LoggerInitialized message in return:

        private void Init(IActorRef sender)
        {
            using (var consoleColour = new ScopedConsoleColour(ConsoleColor.Green))
                Console.WriteLine("Init");

            sender.Tell(new LoggerInitialized());
        }

Aside from sending back the required message, I’m also logging the init operation itself, so that we can later observe the sequence of events. I am using my trusty ScopedConsoleColour class to change the colour, and then reset it back after the message has been written.

If you don’t send the LoggerInitialized message back, the actor system reports a timeout from initialising the logger, and basically you get no logging. (Well, ironically, the timeout itself is logged… presumably using the DefaultLogger as a fallback.)

akkanet-logging-notinitialized

Now we can implement our Log() helper method:

        private void Log(LogLevel level, string message)
        {
            ConsoleColor colour = ConsoleColor.Gray;

            switch (level)
            {
                case LogLevel.DebugLevel:
                    colour = ConsoleColor.Gray;
                    break;
                case LogLevel.InfoLevel:
                    colour = ConsoleColor.White;
                    break;
                case LogLevel.WarningLevel:
                    colour = ConsoleColor.Yellow;
                    break;
                case LogLevel.ErrorLevel:
                    colour = ConsoleColor.Red;
                    break;
                default: // shouldn't happen
                    goto case LogLevel.InfoLevel;
            }

            using (var consoleColour = new ScopedConsoleColour(colour))
                Console.WriteLine(message);
        }

Here we’re doing nothing but using a different colour per level, and writing the message to the console (which is pretty much what StandardOutLogger does). Remember, the level is already part of the message, so we don’t need to format it into the output message. (And if you’re outraged at the use of goto above, I suggest you read about goto case in C#.)

Actor Life Cycle Hooks

If your custom logger depends on external resources (which is most likely the case) such as the filesystem or a database, you will want to initialise those resources when the logger actor is created, and clean them up when it is destroyed. That work typically goes into actor life cycle hooks, i.e. overridable methods that allow you to run arbitrary code when an actor starts, stops, or restarts.

We don’t need to do this for ConsoleLogger, so we will simply log the start and stop operation instead. However, we will use these hooks more realistically when we implement the FileLogger.

        protected override void PreStart()
        {
            base.PreStart();

            using (var consoleColour = new ScopedConsoleColour(ConsoleColor.Green))
                Console.WriteLine("PreStart");
        }

        protected override void PostStop()
        {
            using (var consoleColour = new ScopedConsoleColour(ConsoleColor.Green))
                Console.WriteLine("PostStop");

            base.PostStop();
        }

We can now run this and see the logging in action:

akkanet-logging-console

Now, for something interesting, put a breakpoint inside PostStop(), and press ENTER to cause the program to continue and terminate. One would expect PostStop() to run as the ActorSystem is shutting down. But in fact, it doesn’t.

Next, go back to the main program, and add a second Console.ReadLine() at the end:

            using (var actorSystem = ActorSystem.Create("MyActorSystem"))
            {
                var logger = Logging.GetLogger(actorSystem, actorSystem, null);
                logger.Info("ActorSystem created!");

                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
            }

            Console.ReadLine();

Run it again, and when you press ENTER, the breakpoint is hit and the PostStop event is written to the console while waiting for the second ENTER:

akkanet-logging-poststop

When we disposed the ActorSystem earlier, the program terminated before the ActorSystem had the chance to do its cleanup work. It appears that when the ActorSystem shuts down, it doesn’t clean resources right away; most likely it is done using asynchronous messaging just like in the rest of Akka .NET. For this reason, in your program’s stopping code, you might want to wait a little bit between destroying the ActorSystem and actually letting the application terminate, in order to let it gracefully free its resources.

Writing the FileLogger

We will now write a second custom logger, this time one that writes to file.

First, change the HOCON configuration to use the new logger.

          loggers = ["AkkaNetCustomLogger.Loggers.FileLogger, AkkaNetCustomLogger"]

Next, let’s write the FileLogger. As with the ConsoleLogger, we need to handle the same five messages:

    public class FileLogger : ReceiveActor
    {
        private StreamWriter writer;

        public FileLogger()
        {
            ReceiveAsync<Debug>(async e => await this.LogAsync(e.ToString()));
            ReceiveAsync<Info>(async e => await this.LogAsync(e.ToString()));
            ReceiveAsync<Warning>(async e => await this.LogAsync(e.ToString()));
            ReceiveAsync<Error>(async e => await this.LogAsync(e.ToString()));
            Receive<InitializeLogger>(_ => Sender.Tell(new LoggerInitialized()));
        }

        // ...
    }

The logger keeps a reference to a StreamWriter, which wraps the file we will be writing to.

The LogAsync() method simply dumps the messages into that StreamWriter (remember, streams and toilets must always be flushed):

        private async Task LogAsync(string message)
        {
            await this.writer.WriteLineAsync(message);
            await this.writer.FlushAsync();
        }

We can open the file itself either during the InitializeLogger handler or in PreStart(). Let’s use a fixed filename for now:

        protected override void PreStart()
        {
            base.PreStart();

            string filePath = "log.txt";
            var fileStream = File.OpenWrite(filePath);
            this.writer = new StreamWriter(fileStream);
        }

We can then do the cleanup in PostStop():

        protected override void PostStop()
        {
            // dispose the StreamWriter, and implicitly the
            // underlying FileStream with it
            this.writer.Dispose();

            base.PostStop();
        }

We only need to Dispose() our StreamWriter; doing that will automatically also close the underlying FileStream.

Now, while this is enough to log to file, there is a problem. We can’t actually use another program to read the log file while the program is running:

akkanet-logging-cantread

We can fix this by changing the way we open the file.

        protected override void PreStart()
        {
            base.PreStart();

            string filePath = "log.txt";
            var fileStream = File.Open(filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
            this.writer = new StreamWriter(fileStream);
        }

You’ll see that the log messages are now written to file:

akkanet-logging-fileoutput

However, there is another problem. If you press ENTER to close the program, the following happens:

akkanet-logging-race

Upon further inspection, it seems that logging messages are coming in around the same time that PostStop() is running, causing a race condition on the underlying resource. I’ve opened a bug report for this, but until this is sorted, you can flush synchronously as a workaround:

        private async Task LogAsync(string message)
        {
            await this.writer.WriteLineAsync(message);
            this.writer.Flush();
        }

So, if there is this problem, how do existing logging adapters that have a file-based component (e.g. NLog) do their cleanup? Well, I’ve checked a few, and it seems they don’t.

Loading Custom Configuration

We’ve managed to write a file logger, but we’re using a fixed filename. How can we make it configurable?

It turns out we can just add an arbitrary setting anywhere in the HOCON configuration, and read it from inside the actor. So, let’s add this:

        akka
        {
          loglevel = DEBUG
          loggers = ["AkkaNetCustomLogger.Loggers.FileLogger, AkkaNetCustomLogger"]
          logfilepath = "logfile.txt"

We can get to the setting we want using the configuration system in Akka .NET:

        protected override void PreStart()
        {
            base.PreStart();

            string filePath = "log.txt";

            filePath = Context.System.Settings.Config
                .GetString("akka.logfilepath", filePath);

            var fileStream = File.Open(filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
            this.writer = new StreamWriter(fileStream);
        }

Basically we’re reading the “akka.logfilepath” key from the HOCON config. We’re also passing in filePath as a default in case the setting is not found.

Running Multiple Loggers

So far we’ve been using either one logger or the other. But if you notice, the loggers configuration in HOCON is actually an array. Thus there is nothing stopping us from using multiple loggers at once:

        akka
        {
          loglevel = DEBUG
          loggers = ["AkkaNetCustomLogger.Loggers.FileLogger, AkkaNetCustomLogger",
                     "AkkaNetCustomLogger.Loggers.ConsoleLogger, AkkaNetCustomLogger"]
          logfilepath = "logfile.txt"

Yes, it works:

akkanet-logging-multiple

Akka .NET IActorRef: Local or Remote?

Akka .NET supports location transparency. When you use an IActorRef, your application shouldn’t care whether that actor is running on the same machine or somewhere else on the network. You can change where an actor runs as a matter of configuration, and your application will never know the difference.

Although an application shouldn’t depend on the physical location of an actor to perform its logic, knowing where an actor is running can be useful (e.g. when troubleshooting issues).

akkanet-islocal

There is an IsLocal property that you can use to tell whether an actor is running locally or remotely. However, this is not immediately accessible from the IActorRef. Instead, you need to cast your IActorRef to an InternalActorRefBase to be able to use it:

(localChatActor as InternalActorRefBase).IsLocal

If you’re working with an ActorSelection (which you probably are if you’re using remote actors), then you will first want to get to the particular IActorRef of the actor. You can do this via the ActorSelection‘s Anchor property.

(remoteChatActor.Anchor as InternalActorRefBase).IsLocal

This will allow you to check whether an actor is running locally or remotely. But remember: use this only for diagnostic purposes, and don’t make your application code dependent on it.