From 37696e1ada5fa2a566bf5fbe61a477f61520c1e2 Mon Sep 17 00:00:00 2001 From: Jesse Gibson Date: Wed, 16 Nov 2016 16:40:14 -0700 Subject: [PATCH] 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. --- lib/wsp/client.js | 22 +++++++++++++++++----- lib/wsp/server-push.js | 23 +++++++++++++++++++++-- lib/wsp/server.js | 20 ++++++++++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/lib/wsp/client.js b/lib/wsp/client.js index d39a53df..808eb91b 100644 --- a/lib/wsp/client.js +++ b/lib/wsp/client.js @@ -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. diff --git a/lib/wsp/server-push.js b/lib/wsp/server-push.js index e4c77f7e..55093ff6 100644 --- a/lib/wsp/server-push.js +++ b/lib/wsp/server-push.js @@ -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, diff --git a/lib/wsp/server.js b/lib/wsp/server.js index b4e6fd16..c3fa0385 100644 --- a/lib/wsp/server.js +++ b/lib/wsp/server.js @@ -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: {