The NoPE-Dispatcher uses one ConnectivityManager. The manager observes the connection and remotly connected dispatchers (and their ConnectivityManager).
The Manager detects newly connected dispatchers and disconnected dispatchers. Additionally, it sends a StatusMessage (in the form of INopeStatusInfo).
This status message is interpreted as heartbeat. The ConnectivityManager checks those heartbeats with a defined interval. If a specific amount of time is
ellapsed, the remote dispatcher is marked as slow -> warning -> dead. After an additional delay in the state dead the dispatcher is altough removed.
Because we asume, that NoPE is running on different computing nodes, we have to be able to synchronize the time between those elements. Therefore the
ConnectivityManager is able to sync the time (by providing a timestamp and an additional delay that was needed to get to the call (for instance ping / 2))
// First lets install nope using npm constnope = require("../dist-nodejs/index.nodejs")
// Create a communicator: // We will use the event layer (which just runs internally) constcommunicator = nope.getLayer("event");
// Lets create our dispatcher
// 1. Dispatcher simulates our local system constlocalDispatcher = nope.dispatcher.getDispatcher({ communicator, id:"local" }, { singleton:false, useBaseServices:false });
For Jupyter we need an extra async wrapper to wait for initalizing the dispatcher:
Now that we have implemented our listeners and have seen the connected dispatchers (which is only the "local"-dispatchre), We will add an additional dispatcher. This should result in calling our onChange-listener. Additionally, we wait until our remoteDispatcher is initalized
Now we want to see, which system is the current master. This should be our local.
// We expect to be the master, because the localDispatcher has been created first. console.log("master =", localDispatcher.connectivityManager.master.id);
`master = local`
We can now force the remote dispatcher to be our master, by setting the master. (For this purpose we can later use a base service ==> then we just have to call the service)
// Our messaging is async ==> we wait an amount of time setTimeout(() =>$$.done(),1000);
// We expect the master to be the remote. console.log("master =", localDispatcher.connectivityManager.master.id); console.log("master-info =", localDispatcher.connectivityManager.master);
localDispatcher.connectivityManager.setTimings({ // our system will send every 50 ms an heartbeat. sendAliveInterval:250, // we will check that after checkInterval:125, // will mark dispatchers as slow after not receiving heartbeats for 50ms slow:500, // we will mark dispatchers with a warning flag after 50 ms warn:1000, // we mark it as dead after 0.5 s dead:2000, // We will remove the dispatcher after 1 s remove:3000, });
remoteDispatcher.connectivityManager.setTimings({ // our system will send every 50 ms an heartbeat. sendAliveInterval:5000, });
// We reset the timeouts. setTimeout(() =>localDispatcher.connectivityManager.setTimings({}), 3000); setTimeout(() =>remoteDispatcher.connectivityManager.setTimings({}), 3000); setTimeout(() =>$$.done(), 5000);
Author
Martin Karkowski
Email
m.karkowski@zema.de
NoPE - Connectivity Manager
The following elements are exported:
The NoPE-Dispatcher uses one
ConnectivityManager
. The manager observes the connection and remotly connected dispatchers (and theirConnectivityManager
). The Manager detects newly connected dispatchers and disconnected dispatchers. Additionally, it sends a StatusMessage (in the form ofINopeStatusInfo
). This status message is interpreted as heartbeat. TheConnectivityManager
checks those heartbeats with a defined interval. If a specific amount of time is ellapsed, the remote dispatcher is marked asslow
->warning
->dead
. After an additional delay in the statedead
the dispatcher is altough removed.Master
Defaultly a
ConnectivityManager
is elected asmaster
. The master is defined as theConnectivityManager
with the highestupTime
.Synchronizing time
Because we asume, that NoPE is running on different computing nodes, we have to be able to synchronize the time between those elements. Therefore the
ConnectivityManager
is able to sync the time (by providing atimestamp
and an additionaldelay
that was needed to get to the call (for instanceping / 2
))see here for the details in Jupyter: https://n-riesco.github.io/ijavascript/doc/async.ipynb.html
Now we want to listen to newly connected dispatchers. For this purpose, we create an observer, which will listen to changes.
Additionally we want to show the currently connected dispatchers. In this data the own dispatcher will allways be included:
Now that we have implemented our listeners and have seen the connected dispatchers (which is only the
"local"
-dispatchre), We will add an additional dispatcher. This should result in calling ouronChange
-listener. Additionally, we wait until ourremoteDispatcher
is initalizedNow we want to see, which system is the current master. This should be our
local
.We can now force the remote dispatcher to be our master, by setting the master. (For this purpose we can later use a base service ==> then we just have to call the service)
Now lets see what happens if we adapt the heartbeat intervall of our local instance. We want to receive every 50 ms a heartbeat: