Im playing with using akka.Net to develop a plugin architecture whereby each dll that contains one or more plugins is loaded into its own AppDomain
and a new actor system is initialized ready to recieve messages from the "Host".
I become unstuck trying to get this to work with multiple plugins.
So the Host config looks like:
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
applied-adapters = []
transport-protocol = tcp
port = 50003
hostname = localhost
}
}
}
And the plugin config looks like:
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
applied-adapters = []
transport-protocol = tcp
port = 50004
hostname = localhost
}
}
(there are many of these)
My question is how do i get messages from the Host to all of the plugins?
In order to actually form an association between the client and the server, one of the nodes has to attempt contact with the other. Remote associations are formed lazily! In order to form an association with a remote ActorSystem, we have to have an Address for that ActorSystem.
Both ActorSystem instances start, open their transports and bind them to the configured addresses (which creates an inbound endpoint for each) and then waits for incoming association attempts from elsewhere. In order to actually form an association between the client and the server, one of the nodes has to attempt contact with the other.
The design of remoting is driven by two (related) design decisions: Communication between involved systems is symmetric: if a system A can connect to a system B then system B must also be able to connect to system A independently.
Remote workers are one of the biggest barriers for internal communicators but this insight demonstrates they don’t need to be.
The best recommendation is to use Akka.Cluster. Here's a well-documented example: https://github.com/petabridge/akkadotnet-code-samples/tree/master/Cluster.WebCrawler
Edit - removed suggestion to use dynamic port. Much better off using static ones so node reboots can be handled correctly.
Have each plugin config use a plugin-specific port (akka.remote.helios.tcp.port = 1231
) and then define a clustered router that talks to actor systems fulfilling specific roles.
/api/broadcaster {
router = broadcast-group
routees.paths = ["user/api"]
cluster {
enabled = on
max-nr-of-instances-per-node = 1
allow-local-routees = on
use-role = crawler
}
}
This router, deployed at the path user/api/broadcaster
on some node can communicate (via the Broadcast
routing strategy) with any actor deployed at path user/api
on any node in the cluster with role crawler
without needing to look up IP addresses, ports, or any of that crap.
You configure a node's clustering information via the following section in Akka.NET's config:
cluster {
#manually populate other seed nodes here, i.e. "akka.tcp://[email protected]:4053"
seed-nodes = ["akka.tcp://[email protected]:4053"]
roles = [crawler]
}
Seed nodes - has to be a well-known, statically-defined port and IP address. Read the article for an explanation on why this is important.
Roles - comma-delimited strings that define what this particular nodes' capabilities are. They're more like tags. You can use them inside clustered routers (like the one I showed earlier) to articulate which types of nodes you want to communicate with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With