improved route discovery
This commit is contained in:
parent
33731778ea
commit
e695fc9b6d
@ -2,11 +2,11 @@ package kernel.net;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
import kernel.net.Package.NetworkID;
|
||||
import kernel.peripherals.Peripherals.Peripheral;
|
||||
import kernel.Log;
|
||||
import kernel.KernelEvents;
|
||||
import haxe.Exception;
|
||||
import util.Promise;
|
||||
import kernel.Timer;
|
||||
import cc.OS;
|
||||
|
||||
@ -24,12 +24,12 @@ class Net {
|
||||
|
||||
public final onNewNeigbor:Signal<Int>;
|
||||
|
||||
private final networkID:Int = OS.getComputerID();
|
||||
private var responseBus:Map<Int,Callback<Package>> = new Map();
|
||||
private var protoHandlers:Map<String, Callback<Package>> = new Map();
|
||||
public final networkID:NetworkID = OS.getComputerID();
|
||||
private final responseBus:Map<Int, Callback<Package>> = new Map();
|
||||
private final protoHandlers:Map<String, Callback<Package>> = new Map();
|
||||
private var allModems:Array<kernel.peripherals.Modem>;
|
||||
private var routingTable:Map<Int, kernel.peripherals.Modem> = new Map();
|
||||
private final onNewNeigborTrigger: SignalTrigger<Int> = Signal.trigger();
|
||||
private final routingTable:Map<NetworkID, kernel.peripherals.Modem> = new Map();
|
||||
private final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger();
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private function new() {
|
||||
@ -52,24 +52,27 @@ class Net {
|
||||
discoverNeighbors();
|
||||
}
|
||||
|
||||
/**
|
||||
Called when a new package comes in.
|
||||
**/
|
||||
private function handelIncomming(pack:Package, ?addr:String) {
|
||||
switch pack.type {
|
||||
case Data(_):
|
||||
routeTo(pack);
|
||||
routeToProto(pack);
|
||||
case DataNoResponse(_):
|
||||
routeTo(pack);
|
||||
case Response | RouteDiscoverResponse:
|
||||
routeToProto(pack);
|
||||
case Response:
|
||||
if (responseBus.exists(pack.msgID)) {
|
||||
responseBus[pack.msgID].invoke(pack);
|
||||
}
|
||||
case RouteDiscover:
|
||||
handleRoute(pack, addr);
|
||||
case RouteDiscover(_) | RouteDiscoverResponse(_):
|
||||
handleRouteDiscover(pack, addr);
|
||||
}
|
||||
}
|
||||
|
||||
private function newRoutPackage():Package {
|
||||
private function newRoutDiscoverPackage():Package {
|
||||
var pack:Package = {
|
||||
type: RouteDiscover,
|
||||
type: RouteDiscover(getAllNeighbors()),
|
||||
toID: BRODCAST_PORT,
|
||||
msgID: generateMessageID(),
|
||||
fromID: networkID,
|
||||
@ -79,33 +82,45 @@ class Net {
|
||||
return pack;
|
||||
}
|
||||
|
||||
/**
|
||||
Send out discover packages on all modems.
|
||||
**/
|
||||
private function discoverNeighbors() {
|
||||
for (modem in allModems) {
|
||||
var pack = newRoutPackage();
|
||||
var pack = newRoutDiscoverPackage();
|
||||
|
||||
var timeout:Timer = null;
|
||||
|
||||
responseBus[pack.msgID] = ((response:Package)->{
|
||||
addRoute(response.fromID, modem.addr);
|
||||
});
|
||||
|
||||
timeout = new Timer(MESSAGE_TIMEOUT, () -> {
|
||||
responseBus.remove(pack.msgID);
|
||||
});
|
||||
|
||||
modem.transmit(BRODCAST_PORT, OS.getComputerID(), pack);
|
||||
modem.transmit(BRODCAST_PORT, networkID, pack);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleRoute(pack:Package, addr:String) {
|
||||
/**
|
||||
Handle incomming packages that involve route discovery.
|
||||
**/
|
||||
private function handleRouteDiscover(pack:Package, addr:String) {
|
||||
addRoute(pack.fromID, addr);
|
||||
|
||||
var forward = getAllNeighbors().filter(i -> i == pack.fromID);
|
||||
|
||||
switch pack.type{
|
||||
case RouteDiscoverResponse(reachableIDs):
|
||||
for (id in reachableIDs) {
|
||||
addRoute(id, addr);
|
||||
}
|
||||
return; // Dont respond to a response
|
||||
case RouteDiscover(reachableIDs):
|
||||
for (id in reachableIDs) {
|
||||
addRoute(id, addr);
|
||||
}
|
||||
default:
|
||||
throw new Error("Expcted RouteDiscover or RouteDiscoverResponse type");
|
||||
}
|
||||
|
||||
// Respond to peer
|
||||
var response:Package = {
|
||||
toID: pack.fromID,
|
||||
fromID: OS.getComputerID(),
|
||||
fromID: networkID,
|
||||
msgID: pack.msgID,
|
||||
type: RouteDiscoverResponse,
|
||||
type: RouteDiscoverResponse(forward),
|
||||
data: null
|
||||
}
|
||||
|
||||
@ -114,8 +129,12 @@ class Net {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Called when a route to a client has been disoverd.
|
||||
Its posible to be called multiple times with the same id but different addr.
|
||||
**/
|
||||
private function addRoute(toID:Int, addr:String) {
|
||||
Log.debug("Added new route to " + toID + " via " + addr);
|
||||
Log.info("Added new route to " + toID + " via " + addr);
|
||||
routingTable.set(toID, allModems.find(item -> item.addr == addr));
|
||||
this.onNewNeigborTrigger.trigger(toID);
|
||||
}
|
||||
@ -164,7 +183,10 @@ class Net {
|
||||
sendRaw(response);
|
||||
}
|
||||
|
||||
private function routeTo(pack:Package) {
|
||||
/**
|
||||
Send to package to the localy register handler based on the proto
|
||||
**/
|
||||
private function routeToProto(pack:Package) {
|
||||
var proto:String = switch pack.type {
|
||||
case Data(proto):
|
||||
proto;
|
||||
@ -181,6 +203,9 @@ class Net {
|
||||
protoHandlers[proto].invoke(pack);
|
||||
}
|
||||
|
||||
/**
|
||||
Just send the package to the right modem.
|
||||
**/
|
||||
private function sendRaw(pack:Package) {
|
||||
if (pack.toID == networkID) {
|
||||
// Loopback
|
||||
@ -195,7 +220,11 @@ class Net {
|
||||
}
|
||||
}
|
||||
|
||||
public function sendAndAwait(dest:Int, proto:String, data:Dynamic):Promise<Package> {
|
||||
/**
|
||||
Send a message and wait for a response.
|
||||
**/
|
||||
public function sendAndAwait(dest:NetworkID, proto:String, data:Dynamic):Promise<Package> {
|
||||
|
||||
return new Promise<Package>((resolve, reject) -> {
|
||||
var pack:Package = {
|
||||
toID: dest,
|
||||
@ -216,10 +245,13 @@ class Net {
|
||||
|
||||
timeout = new Timer(MESSAGE_TIMEOUT, () -> {
|
||||
responseBus.remove(pack.msgID);
|
||||
reject(new Exception("Timeout"));
|
||||
reject(new Error(InternalError,"Message timeout"));
|
||||
});
|
||||
|
||||
sendRaw(pack);
|
||||
|
||||
// No callback link for you
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@ -236,8 +268,4 @@ class Net {
|
||||
public function removeProto(proto:String) {
|
||||
protoHandlers.remove(proto);
|
||||
}
|
||||
|
||||
public function getNeigbors():Array<Int> {
|
||||
return this.routingTable.mapi((index, item) -> {return index;});
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,21 @@
|
||||
package kernel.net;
|
||||
|
||||
typedef NetworkID = Int;
|
||||
|
||||
enum PackageTypes {
|
||||
Data(proto:String);
|
||||
DataNoResponse(proto:String);
|
||||
Response;
|
||||
RouteDiscover();
|
||||
RouteDiscoverResponse();
|
||||
RouteDiscover(reachableIDs: Array<NetworkID>);
|
||||
RouteDiscoverResponse(reachableIDs: Array<NetworkID>);
|
||||
}
|
||||
|
||||
/**
|
||||
Representing a network package.
|
||||
**/
|
||||
@:structInit class Package {
|
||||
public final fromID:Int;
|
||||
public final toID:Int;
|
||||
public final fromID:NetworkID;
|
||||
public final toID:NetworkID;
|
||||
public final msgID:Int;
|
||||
public final type:PackageTypes;
|
||||
public final data:Dynamic;
|
||||
|
Loading…
Reference in New Issue
Block a user