Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Akka.NET Remote between Linux and Windows

Tags:

c#

linux

akka.net

I have a distributed system of actors, some on Windows, and some on Linux machine. Sometimes one actor may need to connect other actor and make some communications. Of course, there are cases when one of them is on Windows, and other is on Linux system.

Actors connect each other via ActorSelection. There problem is, that when Windows actor is trying to communicate with Linux one, all works fine. But when Linux actor initiating communication, the ActorSelection.ResolveOne failes.

I've made a little sample here:

static void Main(string[] args)
{
    ActorSystem system = ActorSystem.Create("TestSystem");
        system.ActorOf(Props.Create(() => new ConnectActor()), "test");

        while (true)
        {
            var address = Console.ReadLine();
            if (string.IsNullOrEmpty(address))
            {
                system.Terminate();
                return;
            }

            var remoteAddress = $"akka.tcp://{system.Name}@{address}/user/test";
            try
            {
                var actor = system.ActorSelection(remoteAddress).ResolveOne(TimeSpan.FromMilliseconds(5000)).Result;
                Console.WriteLine("Resolved: " + actor.Path);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed: " + ex.Message);
            }
        }
}

Configuration in app.config is the following:

akka {
          loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"]
          suppress-json-serializer-warning = on
          loglevel = "DEBUG"
          log-config-on-start = on

          actor {
            provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"

            debug {
              receive = on
              autoreceive = on
              lifecycle = on
              event-stream = on
              unhandled = on
            }
          }

          remote {    
            log-remote-lifecycle-events = DEBUG
            log-received-messages = on

            helios.tcp {
                transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
                transport-protocol = tcp
                applied-adapters = []
                port = 9000
                hostname = "0.0.0.0"
                public-hostname = "192.168.0.251" // This is different for different hosts, of course
            }
         }
      }

The public-hostname is publicly available ip address.

So, here are the cases:

  • When running Windows/Windows, both instances see each other (I give them remote address - they output "Resolved ")
  • When running Windows/Linux, and give linux actor's address to windows actor, it outputs "Resolved". So windows connects linux with no problem. After that giving windows actor's address to linux actor also gives "Resolved" - I suppose, the connection is already established and there is no real handshakes passing
  • BUT when running Windiws/Linux and give windows actor's address to linux actor, it gives "Failed". No messages about any errors or dropping packages. At the end of the log there is the following:

Akka.Remote.Transport.AkkaProtocolManager|now supervising akka://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0.252%5D%3A36983-1|||| 13:20:08.3766|DEBUGAkka.Remote.Transport.ProtocolStateActor|Started (Akka.Remote.Transport.ProtocolStateActor)|||| 13:20:08.3922|DEBUG|Akka.Remote.Transport.ProtocolStateActor|Stopped||||

The issue with similar logs is described here: Akka.net starting and stopping with no activity The reason there is that system protocols are not compatible. Is this the same issue? As I got from Akka.NET docs and release notes, it has full linux support...

So, am I missing something in configuration? Can anybody make this sample work with Linux -> Windows connection?

like image 875
Igor Fedchenko Avatar asked Nov 08 '22 10:11

Igor Fedchenko


1 Answers

The issue here appears to be that Mono is using an IPV6 address mapped to IPV4 in its bound address for some reason.

akka://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0.252%5D%3A36983-1

If you decode this URL that gets translated to

akkaProtocol-tcp://TestSystem@[::ffff:192.168.0.252]:36983-

So I think what is happening here is that outbound address Helios is supposed to parse from that is getting screwed up on the Linux side, so it attempts to connect to a mal-formed address that isn't the same as the one Windows listens on. Something platform-specific in the actor selection URI parsing code is incorrect I suspect.

I've filed a bug here: https://github.com/akkadotnet/akka.net/issues/2254

like image 78
Aaronontheweb Avatar answered Nov 15 '22 06:11

Aaronontheweb