My Journey on learning F#
September 19, 2020 • 4 min read • Also published at Notion. • Open • Code
Location transparency
Location transparency means that whenever you send a message to an actor, you don’t need to know where they are within an actor system, which might span hundreds of computers. You just have to know that actors’ address.
Actors work just the same way - in Akka.NET every actor has an address that contains the following parts:
- Protocol: Just like HTTP, HTTPS, FTP, etc, Akka.Net supports multiple protocol in order to send messages. If you’re using remoting or clustering, you’ll typically use a socket transport like akka.tcp:// or akka.udp:// to communicate between nodes
- ActorSystem - every
ActorSystem
instance in Akka.NET has to be given a name upon startup, and that name can be shared by multiple processes or machines that are all participating in a distributedActorSystem
. - Address - if you’re not using remoting, then the address portion of an
ActorPath
can be omitted. But this is used to convey specific IP address / domain name and port information used for remote communication between actor systems. - Path - this is the path to a specific actor at an address. It’s structure just like a URL path for a website, with all user-defined actors stemming off of the
/user/
root actor.
// RemoteActor.fsx#r "nuget: Akka.FSharp" #r "nuget: Akka.Remote"open Systemopen Akka.Actoropen Akka.Configurationopen Akka.FSharplet config = Configuration.parse @"akka { actor.provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" remote.helios.tcp { hostname = ""127.0.0.1"" port = 9001 } }"let system = System.create "RemoteFSharp" configlet echoServer = spawn system "EchoServer" <| fun mailbox -> let rec loop() = actor { let! message = mailbox.Receive() let sender = mailbox.Sender() printfn "echoServer called" match box message with | :? string -> sender <! sprintf "Echo: %s" message return! loop() | _ -> failwith "Unknown message" } loop()Console.ReadLine() |> ignore
In your terminal run RemoteActor.fsx
to let the remote machine listen for messages
dotnet fsi --langversion:preview RemoteActor.fsx
Now lets write some Local actor code
//LocalActor.fsx#r "nuget: Akka.FSharp" #r "nuget: Akka.Remote"open Systemopen Akka.Actoropen Akka.Configurationopen Akka.FSharplet configuration = ConfigurationFactory.ParseString( @"akka { actor { provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" deployment { /remoteecho { remote = ""akka.tcp://RemoteFSharp@127.0.0.1:9001"" } } } remote { helios.tcp { port = 0 hostname = ""127.0.0.1"" } } }")let system = ActorSystem.Create("RemoteFSharp", configuration)let echoClient = system.ActorSelection("akka.tcp://RemoteFSharp@127.0.0.1:9001/user/EchoServer")let task = echoClient <? "F#!"let response = Async.RunSynchronously (task, 1000)printfn "Reply from remote %s" (string(response))
Open up another terminal and run LocalActor.fsx
to let the remote machine listen for messages
dotnet fsi --langversion:preview LocalActor.fsx
You should be able to see the following on your terminal