Prevent most broadcast storms

Better de-duplication on messages sent for GET and PUT requests,
allowing full circular connections without blowing up your computer.
Sadly, this broke some things against the previous version, so per
@amark's request I'm publishing so he can debug.
This commit is contained in:
Jesse Gibson 2016-11-16 16:40:14 -07:00
parent 2317a54d45
commit 37696e1ada
3 changed files with 56 additions and 9 deletions

View File

@ -246,6 +246,11 @@ Gun.on('get', function (at) {
var gun = at.gun;
var opt = at.opt || {};
var peers = opt.peers || gun.Back('opt.peers');
var server = Tab.server || {};
var duplicated = server.msg || function () {
return false;
};
if (!peers || Gun.obj.empty(peers)) {
Gun.log.once('peers', 'Warning! You have no peers to connect to!');
@ -264,20 +269,27 @@ Gun.on('get', function (at) {
'$': at.get,
};
if (duplicated(msg['#'])) {
return;
}
// Listen for a response.
// TODO: ONE? PERF! Clear out listeners, maybe with setTimeout?
Tab.on(msg['#'], function (err, data) {
var id = Gun.text.random();
var root = at.gun.Back(Infinity);
var obj = {
'#': id,
'@': at['#'],
err: err,
put: data,
// Flag, prevents rebroadcast.
nopush: true,
};
if (data) {
at.gun.Back(-1).on('out', obj);
} else {
at.gun.Back(-1).on('in', obj);
}
root.on(data ? 'out' : 'in', obj);
});
// Broadcast to all other peers.

View File

@ -45,12 +45,19 @@ function ready (socket, cb) {
* @return {undefined}
*/
function request (context, clients, cb) {
var id = context['#'] || Gun.text.random(9);
Gun.on(id, function (err, data, event) {
cb(err, data);
event.off();
});
Gun.obj.map(clients, function (client) {
ready(client, function () {
var msg = {
headers: {},
body: {
'#': Gun.on.ask(cb),
'#': id,
'$': context.get,
},
};
@ -69,12 +76,19 @@ function request (context, clients, cb) {
* @return {undefined}
*/
function update (context, clients, cb) {
var id = context['#'] || Gun.text.random(9);
Gun.on(id, function (err, data, event) {
cb(err, data);
event.off();
});
Gun.obj.map(clients, function (client) {
ready(client, function () {
var msg = {
headers: {},
body: {
'#': Gun.on.ask(cb),
'#': id,
'$': context.put,
},
};
@ -125,6 +139,7 @@ function attach (gun, server) {
if (!isUsingServer(context.gun, server)) {
return;
}
request(context, pool, function (err, data) {
var response = {
'@': context['#'],
@ -143,6 +158,10 @@ function attach (gun, server) {
return;
}
if (context.nopush) {
return;
}
update(context, pool, function (err, data) {
var ack = {
'!': err || null,

View File

@ -152,8 +152,24 @@ Gun.on('opt', function(at){
// TODO: BUG! server put should push.
}
tran.get = function(req, cb){
var body = req.body, lex = body['$'], reply = {headers: {'Content-Type': tran.json}}, opt;
gun.on('out', {gun: gun, get: lex, req: 1, '#': Gun.on.ask(function(at, ev){
var body = req.body, lex = body['$'], reply = {headers: {'Content-Type': tran.json}};
var graph = gun.Back(Infinity)._.graph;
var node = graph[lex['#']];
var result = Gun.graph.ify(node);
if (node) {
return cb({
headers: reply.headers,
body: {
'#': gun.wsp.msg(),
'@': body['#'],
'$': result,
},
});
}
gun.on('out', {gun: gun, get: lex, req: 1, '#': body['#'] || Gun.on.ask(function(at, ev){
ev.off();
var graph = at.put;
return cb({headers: reply.headers, body: {