From 9e4550706bd263970971de01332e2511a64f37da Mon Sep 17 00:00:00 2001 From: rupumped <nselby3@gatech.edu> Date: Thu, 30 Nov 2017 00:42:38 -0500 Subject: [PATCH] Heartbeat and disconnect --- README.md | 4 +-- sim/manager.js | 66 ++++++++++++++++++++++++++++++++++++-------------- sim/sim.js | 45 +++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index fe5ab2d..330358f 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ elseif packet is standard flood: if LUT has destination address: send packet to port which minimizes C(hops, buffer) = hops + \lambda*buffer as standard packet else: - send packet to all ports + send packet to all ports except one from which it was received elseif packet is ack flood remove packet src. from LUT at that port if it exists @@ -182,7 +182,7 @@ elseif packet is ack flood if LUT has destination address: send packet to port which minimizes C(hops, buffer) = hops + \lambda*buffer as standard ACK else: - send packet to all ports + send packet to all ports except one from which it was received else: write buffer depth to LUT diff --git a/sim/manager.js b/sim/manager.js index ac6d2e1..e13093e 100644 --- a/sim/manager.js +++ b/sim/manager.js @@ -1,10 +1,10 @@ function Manager(self) { self.manager = this; - const STD = 252; - const ACK = 253; - const STF = 254; - const ACF = 255; + const STD = 252; // Standard Message label + const ACK = 253; // Acknowledgement label + const STF = 254; // Standard Flood label + const ACF = 255; // Flood ACK label this.ports = []; this.numports = 0; @@ -19,7 +19,8 @@ function Manager(self) { for (var p = 0; p < numports; p++) { this.addr_table[p] = { dests: {}, - buff: 0 + buff: 0, + heartbeat: false }; } }; @@ -79,9 +80,34 @@ function Manager(self) { // self.log(this.buffer); if (this.buffer.length > 0) { this.handlePacket(this.buffer.shift()); + } else { + self.setColor("black"); } // self.log(`checked buffer of node ${self.id}`); }; + + this.heartbeat = function() { + for (let p=0; p<this.numports; p++) { + this.sendPacket(this.buffer.length, undefined, undefined, undefined, undefined, undefined, p); + } + }; + + this.takePulse = function() { + for (let p=0; p<this.numports; p++) { + if (this.addr_table[p].heartbeat) { + this.addr_table[p].heartbeat = false; + } else { + for (var prop in this.addr_table[p].dests) { + if (this.addr_table[p].dests.hasOwnProperty(prop)) { + this.addr_table[p].dests = {}; + this.addr_table[p].buff = 0; + self.log(`did not receive heartbeat from port ${p}`); + return; + } + } + } + } + }; this.sendPacket = function(start, dest=-1, hopcount=0, src=self.id, size=0, data=null, port=-1) { var packet = { @@ -112,7 +138,10 @@ function Manager(self) { var packet = o.obj; packet.port = port; - if (this.buffer.length < this.maxBufferSize) { + if (packet.start !== STD && packet.start !== ACK && packet.start !== STF && packet.start !== ACF) { + this.addr_table[port].buff = packet.start; + this.addr_table[port].heartbeat = true; + } else if (this.buffer.length < this.maxBufferSize) { this.buffer.push(packet); } }; @@ -127,26 +156,26 @@ function Manager(self) { } if (packet.start === STD) { // Standard Packet + self.setColor("blue"); if (packet.dest === self.id) { // If I am destination const nextPort = this.getMinCostPort(packet.src); // Pick the port to send ACK based off minimizing cost self.log(`got message ${packet.data}. ACKing port ${nextPort}`); - this.sendPacket(ACK, packet.src, 0, self.id, nextPort); + this.sendPacket(ACK, packet.src, undefined, self.id, undefined, undefined, nextPort); } else { packet.hopcount++; // Increment hopcount const nextPort = this.getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost if (nextPort === -1) { // If LUT does not have dest self.log(`flooding message ${packet.data}`); for (let p = 0; p < this.numports; p++) { // Flood packet - if (p !== packet.port) { - this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p); - } + this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p); } } else { // If LUT does have dest, send to that port - self.log(`sending packet ${packet.data}`); + self.log(`sending packet ${packet.data} along port ${nextPort}`); this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort); } } } else if (packet.start === ACK) { // Acknowledgement + self.setColor("red"); if (packet.dest === self.id) { // If I am destination self.log(`got ACK from ${packet.src}`); } else { @@ -155,15 +184,15 @@ function Manager(self) { if (nextPort === -1) { // If LUT does not have dest self.log(`flooding ACK`); for (let p = 0; p < this.numports; p++) { // Flood ACK - if (p !== packet.port) - this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p); + this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p); } } else { // If LUT does have dest, send to that port - self.log(`forwarding ACK`); + self.log(`forwarding ACK along port ${nextPort}`); this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort); } } } else if (packet.start === STF) { // Standard Flood + self.setColor("cyan"); if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it delete this.addr_table[packet.port].dests[packet.dest]; // ...if that node had known, it wouldn't have forwarded it as a flood. const thisFlood = { // Static information within packet for comparison @@ -192,11 +221,12 @@ function Manager(self) { } } } else { // If LUT does have dest, send to that port - self.log(`forwarding message ${packet.data}`); + self.log(`forwarding message ${packet.data} along ${nextPort}`); this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort); } } } else if (packet.start === ACF) { // ACK Flood + self.setColor("magenta"); if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it delete this.addr_table[packet.port].dests[packet.dest]; // ...if that node had known, it wouldn't have forwarded it as a flood. if (packet.dest === self.id) { // If I am destination @@ -220,12 +250,12 @@ function Manager(self) { this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p); } } else { // If LUT does have dest, send to that port - self.log(`forwarding ACK`); + self.log(`forwarding ACK along port ${nextPort}`); this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort); } } - } else { // Buffer Update - this.addr_table[packet.port].buff = packet.start; + } else { // Buffer Update. Should have been handled elsewhere + self.log(`Packet start error`); } }; diff --git a/sim/sim.js b/sim/sim.js index 50c7c76..88dd984 100755 --- a/sim/sim.js +++ b/sim/sim.js @@ -4,14 +4,16 @@ var net = require("./network"), const startupDelay = 100; const connectDelay = 100; const bufferCheckDelay = 1000; +const heartbeatPeriod = 400; // INITIALIZE NETWORK TOPOLOGY HERE var initTopology = [ - [1,2], - [0,3], - [0,4], - [1,4], - [3,2] + [1,2], // 0 + [0,3], // 1 + [0,4,5], // 2 + [1,4], // 3 + [3,2], // 4 + [2] // 5 ]; // Don't touch this code @@ -34,6 +36,12 @@ for (let i = 0; i < initTopology.length; i++) { this.tick(bufferCheckDelay, function() { this.manager.checkBuffer(); }); + this.tick(heartbeatPeriod, function() { + this.manager.heartbeat(); + }); + this.tick(2*heartbeatPeriod, function() { + this.manager.takePulse(); + }); }); for (let j = 0; j < initTopology[i].length; j++) { if (initTopology[i][j] == -1) { @@ -48,17 +56,30 @@ for (let i = 0; i < initTopology.length; i++) { } } +//----------------------------------------------------------------------------// // PUT CUSTOM CODE HERE: - -//send(0, 1, 'hi!', 1000); -//send(3, 3, 'what is up?', 1500); -//disconnect(0, 1, 2, 2, 1700); -//send(2, 2, 'You cannot see this cause we are not connected', 2000); -//send(2, 0, 'we are friends now', 2500); sendPacket(0,4,1,"Hello Four!",1000); -sendPacket(0,4,1,"I love you, Four!",6000) + +// To test link failure, uncomment one. To test node failure, uncomment both. +//disconnect(0,1,2,0,6000); +//disconnect(2,1,4,1,6000); + +// To test how network reacts to heavy traffic at a desired node, uncomment. +//sendPacket(5,2,1,"Distraction 0!",6000); +//sendPacket(5,2,1,"Distraction 1!",6000); +//sendPacket(5,2,1,"Distraction 2!",6000); +//sendPacket(5,2,1,"Distraction 3!",6000); +//sendPacket(5,2,1,"Distraction 4!",6000); +//sendPacket(5,2,1,"Distraction 5!",6000); +//sendPacket(5,2,1,"Distraction 6!",6000); +//sendPacket(5,2,1,"Distraction 7!",6000); +//sendPacket(5,2,1,"Distraction 8!",6000); + +sendPacket(4,0,1,"I love you, One!",8000); + //Don't add stuff below this: +//----------------------------------------------------------------------------// for (let i = 0; i < initTopology.length; i++) { net.add(1, clients[i]); -- GitLab