New MRL Networking System

Hey y'all

This is just me trying to organize my thoughts around the new networking system so I can figure out the best way to implement client libraries. First thing I'll be doing once this system is finished is to update mrlpy and to create a C++ client library, using the information here, so if anything's wrong feel free to correct me.

So, first thing I noticed was the addition of the ServiceEnvironment. From what I can see, the ServiceEnvironment is what represents a foreign MRL instance. It contains data such as URI, foreign service directory, and system platform information. From what I see it doesn't implement any methods to communicate with the foreign instance, that seems to be left to other classes. These ServiceEnvironments are added whenever a service is registered that does not correspond to an already existing environment. The environments are stored in a map with the keys being the URIs of the foreign instance, not sure how that's going to work with client libraries that use websocket clients and therefore don't have a server URI (not sure if the client TCP port can be extracted easily from the header information, I'll have to look at that later).

Next thing I see are the Gateway interfaces. These appear to be the services implementing the various transports for foreign MRL instances. It seems Runtime will not automatically instantiate these services to provide automatic foreign instance support, which is probably a good thing. That way the end user can determine what interfaces MRL should allow connections on. Gateway services seem to be in charge of managing connections and updating the Runtime registry through various callbacks.

The last thing I need, how messages are routed through the gateway interfaces instead of to the local service environment, I can't seem to find, but I know it calls the sendRemote() method on a gateway. That's all I need for now, pretty sure.


So far, the only services implementing Gateway that I see are RemoteAdapter (implementing the full Gateway interface with native Java object streams over TCP/UDP, not compatible with other languages), Xmpp, and WebGui (neither of which implement any of the Gateway methods). MQTT should implement Gateway in the future, maybe Serial too (for, say, two RPis connected via the serial header, possibly Arduinos, although the current protocol for Arduinos seems to work just fine).


So, now comes the expected actions to register a service. This is just what I can gather after looking at the comments and logic in RemoteAdapter, Gateway, and Runtime.

First is to initialize MRL and start up the gateway services.

Second is to connect to a gateway service using the implemented transport. RemoteAdapter, for example, requires transmitting serialized Message objects. For now we'll assume the WebGui will implement its Gateway as the same HTTP API used for the gui itself.

Next, the connecting instance sends a register command to the base instance with a null service name and null data. This message is routed to Runtime and it registers the new running instance.

Once the instance is registered, it sends another register command for each service running with the serialized ServiceInterface of the service as the data (so each client library would need the JSON serialized form of the ServiceInterface, or have its types be similar enough to the Java ServiceInterface that automatic JSON serialization would produce a compatible form). After this step, registration is complete and all messages should flow throughout the system in the correct manner. Runtime automatically subscribes to publishState, so any state changes should be automatically reflected in the service registry.


That should be it for my ramblings tonight. Feel free to correct me if anything's wrong here

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
GroG's picture

You got

You got it AutonomicPerfectionist,

I like to think of it this way ...

  • Every instance of MyRobotLab is like a LAN  (local area network) - Treat the services like computers or resources...
  • A few of the services can act like "gateways" - WebGui, RemoteAdapter, Xmpp and yes Mqtt & Kafka. Gateways potentially allow messages to flow in and out of the running instance.
  • My plan for Nixie was for MyRobotLab to have a route table.  This will change current messaging in MRL such that one service will not need to know explicitly that another service exists to send a message, only the "default" gateway.
  • Every instance has its own "Service DNS" (currently Runtime.registry).  Every instance will also have its own identifier (a field in Platform called id - this is like a local domain suffix).

With the route table, dns/registry & suffix searches messaging on MRL will become much more "internet like" except it won't us IP addresses only cnames, suffix search lists & fqdns.

When two instance connect they will not need to provide very much information to interact (currently full registration is being done).  Instead a service can adjust its route table and either blindly send messages through the default route, attempt to register, or accept registration requests.

There's what I consider a "bug" where the definition/type of a service must be defined in Java for registration to work.  I'll be fixing that this release I'll make the registration data JSON which can be provided by any language or service of any type .. This should make MRL much closer to a polyglot system.

Remote service addressing will attempt to resolve using short names first and search through its suffix search list.

Additionally on a local level I hope to use mDns for local instances running to "discover" one another easily.

In short - I hope to make MRL connectivity a lot more "internet like" ..  I mean why not ?  it certainly has worked well for the internet :)


Ray.Edgley's picture

I like networks

The internet comparison is good,

But we need to make sure we don't route everything.

An excellent example is he DHCP service, where it is not routed at all, if it were, then it would cause no end of trouble with address assignments.

In the current implementation of RemoteConector, everything is routed through, so if you create a service after te remote connection is established, it will then create a matching service on the remote MRL, because there is now a new service on the remote MRL, it will create it on the local MRL, and with the creation of that service it creates it on the remote MRL....... this continues til it crashes or you stop it.

Route should not route between each other, that is, with 3 instances of MRL running, a connection between MRL1 and MRL2 and a connection between MRL2 and MRL3.
If a broadcast is made at MRL1, it should not reach MRL3 unless a manually constructed route is established.
The only reason I can think of for creating a route between gateways, is if MRL1 and MRL3 are on different physical networks and MRL2 has a foot in each network, otherwise you just create a connection between MRL1 and MRL3 if it is needed.
In some cases, we don't need the extra data clutter on a small computer that is already under a heavy load (Raspi3 running OpenCV)

Some service should always remain local services only, Runtime being the first example.
Think of these as Broadcast services, in a sense the gateway is also a broadcast service so should not be rebroadcast on to another net without a specific route created.
Runtime deals with the creation and destruction of all service on the local instance of MRL, it doesn't need to know about whats going on with the other instances of MRL, that's the job of the gateway.

GroG's picture

heh .. that infinite

heh .. that infinite ping-pong is a bug ...

ya .. mebbe I didn't word it very well ..

In general the future network update will look like the "internet" in the sense that you can make these comparisons :

  • a running instance == a LAN
  • services in the instances == LAN's computer and resources
  • instances can have gateways and default route ==  So can LANs
  • not everything is routed through a gateway
    but general requests and packets use the default route == Same happens on LANs
  • an instance can have more than one gateway == LANs can have more than one gateway
  • an instance will do name resolution using DNS + suffix list searches == computers on LANs work the same way

The current way DNS, route tables, suffix list searches work will not be "exactly" the same .. but I figure its a good model to follow...

There are higher levels of messaging like the differences between pub/sub and synchronous request/response .. but most of the refactor will be on the lower leves of "name resolution" and weather a service must be registered, and what a registration looks like ... Currently there's a big flaw (what I had mentioned before) that a Service is expected to be a Java class - but in this release .. "anything" can register itself to a MRL instance - it just needs to send the methods it can do, and their parameters (probably in a json description)