87 lines
2.1 KiB
JavaScript
87 lines
2.1 KiB
JavaScript
|
|
'use strict';
|
||
|
|
|
||
|
|
var JX = require('./javelin').JX;
|
||
|
|
|
||
|
|
JX.install('AphlictPeerList', {
|
||
|
|
|
||
|
|
construct: function() {
|
||
|
|
this._peers = [];
|
||
|
|
|
||
|
|
// Generate a new unique identify for this server. We just use this to
|
||
|
|
// identify messages we have already seen and figure out which peer is
|
||
|
|
// actually us, so we don't bounce messages around the cluster forever.
|
||
|
|
this._fingerprint = this._generateFingerprint();
|
||
|
|
},
|
||
|
|
|
||
|
|
properties: {
|
||
|
|
},
|
||
|
|
|
||
|
|
members: {
|
||
|
|
_peers: null,
|
||
|
|
_fingerprint: null,
|
||
|
|
|
||
|
|
addPeer: function(peer) {
|
||
|
|
this._peers.push(peer);
|
||
|
|
return this;
|
||
|
|
},
|
||
|
|
|
||
|
|
addFingerprint: function(message) {
|
||
|
|
var fingerprint = this.getFingerprint();
|
||
|
|
|
||
|
|
// Check if we've already touched this message. If we have, we do not
|
||
|
|
// broadcast it again. If we haven't, we add our fingerprint and then
|
||
|
|
// broadcast the modified version.
|
||
|
|
var touched = message.touched || [];
|
||
|
|
for (var ii = 0; ii < touched.length; ii++) {
|
||
|
|
if (touched[ii] == fingerprint) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
touched.push(fingerprint);
|
||
|
|
|
||
|
|
message.touched = touched;
|
||
|
|
return message;
|
||
|
|
},
|
||
|
|
|
||
|
|
broadcastMessage: function(instance, message) {
|
||
|
|
var ii;
|
||
|
|
|
||
|
|
var touches = {};
|
||
|
|
var touched = message.touched;
|
||
|
|
for (ii = 0; ii < touched.length; ii++) {
|
||
|
|
touches[touched[ii]] = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
var peers = this._peers;
|
||
|
|
for (ii = 0; ii < peers.length; ii++) {
|
||
|
|
var peer = peers[ii];
|
||
|
|
|
||
|
|
// If we know the peer's fingerprint and it has already touched
|
||
|
|
// this message, don't broadcast it.
|
||
|
|
var fingerprint = peer.getFingerprint();
|
||
|
|
if (fingerprint && touches[fingerprint]) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
peer.broadcastMessage(instance, message);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
getFingerprint: function() {
|
||
|
|
return this._fingerprint;
|
||
|
|
},
|
||
|
|
|
||
|
|
_generateFingerprint: function() {
|
||
|
|
var src = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
|
||
|
|
var len = 16;
|
||
|
|
var out = [];
|
||
|
|
for (var ii = 0; ii < len; ii++) {
|
||
|
|
var idx = Math.floor(Math.random() * src.length);
|
||
|
|
out.push(src[idx]);
|
||
|
|
}
|
||
|
|
return out.join('');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
});
|