have NTS use DAM + fix other utils

This commit is contained in:
Mark Nadal 2020-09-15 04:22:51 -07:00
parent 356a971ddc
commit bac0e5b7ed
6 changed files with 68 additions and 76 deletions

View File

@ -181,7 +181,7 @@
$('.chat__message-input').val('').focus();
}
chat.map().val(function (msg, id) {
chat.map().once(function (msg, id) {
if (!msg) { return }
var messageList = $('.chat__message-list');
var last = sort(msg.when, messageList.children('li').last());

50
gun.js
View File

@ -189,18 +189,17 @@
}
var dt = dup.track = function(id){
var it = s[id] || (s[id] = {});
it.was = +new Date;
it.was = dup.now = +new Date;
if(!dup.to){ dup.to = setTimeout(dup.drop, opt.age + 9) }
return it;
}
dup.drop = function(age){
var now = +new Date;
Object.keys(s).forEach(function(id){ var it = s[id];
if(it && (age || opt.age) > (now - it.was)){ return }
delete s[id];
});
dup.to = null;
console.STAT && (age = +new Date - now) > 9 && console.STAT(now, age, 'dup drop');
dup.now = +new Date;
setTimeout.each(Object.keys(s), function(id){ var it = s[id]; // TODO: .keys( is slow
if(it && (age || opt.age) > (dup.now - it.was)){ return }
delete s[id];
},0,99);
}
return dup;
}
@ -288,6 +287,7 @@
DBG && (DBG.uc = +new Date);
eve.to.next(msg);
DBG && (DBG.ua = +new Date);
if(msg.nts || msg.NTS){ return } // TODO: This shouldn't be in core, but fast way to prevent NTS spread. Delete this line after all peers have upgraded to newer versions.
msg.out = universe; at.on('out', msg);
DBG && (DBG.ue = +new Date);
}
@ -324,7 +324,7 @@
if(!(tmp = node._)){ err = ERR+cut(soul)+"no meta." } else
if(soul !== tmp['#']){ err = ERR+cut(soul)+"soul not same." } else
if(!(states = tmp['>'])){ err = ERR+cut(soul)+"no state." }
kl = Object.keys(node||{});
kl = Object.keys(node||{}); // TODO: .keys( is slow
}
if(err){
console.log("handle error!", err) // handle!
@ -411,7 +411,7 @@
}
//Gun.window? Gun.obj.copy(node) : node; // HNPERF: If !browser bump Performance? Is this too dangerous to reference root graph? Copy / shallow copy too expensive for big nodes. Gun.obj.to(node); // 1 layer deep copy // Gun.obj.copy(node); // too slow on big nodes
var ack = msg['#'], id = text_rand(9), keys = Object.keys(node||''), soul = ((node||'')._||'')['#'];
// PERF: Consider commenting this out to force disk-only reads for perf testing?
// PERF: Consider commenting this out to force disk-only reads for perf testing? // TODO: .keys( is slow
node && (function got(){
var i = 0, k, put = {};
while(i < 9 && (k = keys[i++])){
@ -618,7 +618,7 @@
var eve = this, cat = eve.as, root = cat.root, gun = msg.$ || (msg.$ = cat.$), at = (gun||'')._ || empty, tmp = msg.put||'', soul = tmp['#'], key = tmp['.'], change = tmp['=']||tmp[':'], state = tmp['>'] || -Infinity, link, sat;
if(tmp && tmp._ && tmp._['#']){ // convert from old format
return setTimeout.each(Object.keys(tmp).sort(), function(k){
return setTimeout.each(Object.keys(tmp).sort(), function(k){ // TODO: .keys( is slow
if('_' == k || !(state = state_is(tmp, k))){ return }
cat.on('in', {put: {'#': tmp._['#'], '.': k, ':': tmp[k], '>': state}});
});
@ -648,10 +648,10 @@
} else {}
eve.to.next(msg); // 1st API job is to call all the listeners.
setTimeout.each(Object.keys(cat.act||''), function(act){ // 1st API job is to call all chain listeners.
setTimeout.each(Object.keys(cat.act||''), function(act){ // 1st API job is to call all chain listeners. // TODO: .keys( is slow
(act = cat.act[act]) && act(msg);
},0,99);
setTimeout.each(Object.keys(cat.echo||''), function(lat){ // & linked chains
setTimeout.each(Object.keys(cat.echo||''), function(lat){ // & linked chains // TODO: .keys( is slow
if(!(lat = cat.echo[lat])){ return }
lat.on('in', msg);
},0,99);
@ -659,7 +659,7 @@
if(u === change){ // 1st edge case: If we have a brand new database, no data will be found.
cat.put = u; // empty out the cache if, for example, alice's car's color no longer exists (relative to alice) if alice no longer has a car.
delete cat.link; // TODO: Empty out links, maps, echos, acks/asks, etc.?
setTimeout.each(Object.keys(cat.next||''), function(get, sat){ // empty out all sub properties.
setTimeout.each(Object.keys(cat.next||''), function(get, sat){ // empty out all sub properties. // TODO: .keys( is slow
if(!(sat = cat.next[get])){ return }
sat.on('in', {get: get, put: u, $: sat.$});
},0,99);
@ -679,7 +679,7 @@
if((tmp = cat.ask||'')['']){
sat.on('out', {get: {'#': link}});
} else {
setTimeout.each(Object.keys(tmp), function(get, sat){ // if sub chains are asking for data.
setTimeout.each(Object.keys(tmp), function(get, sat){ // if sub chains are asking for data. // TODO: .keys( is slow
if(!(sat = cat.ask[get])){ return }
sat.on('out', {get: {'#': link, '.': get}}); // go get it.
},0,99);
@ -781,7 +781,7 @@
if(cat.jam){ return cat.jam.push([cb, as]) }
cat.jam = [[cb,as]];
gun.get(function go(msg, eve){
if(u === msg.put && !cat.root.opt.super && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks <= tmp){ // TODO: super should not be in core code, bring AXE up into core instead to fix?
if(u === msg.put && !cat.root.opt.super && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks <= tmp){ // TODO: super should not be in core code, bring AXE up into core instead to fix? // TODO: .keys( is slow
return;
}
eve.rid(msg);
@ -878,7 +878,7 @@
}
if(k && v){ at.node = state_ify(at.node, k, s, d) } // handle soul later.
else {
as.seen.push(cat = {it: d, link: {}, todo: g? [] : Object.keys(d).sort().reverse()});
as.seen.push(cat = {it: d, link: {}, todo: g? [] : Object.keys(d).sort().reverse()}); // Any perf reasons to CPU schedule this .keys( ?
at.node = state_ify(at.node, k, s, cat.link);
!g && to.push(cat);
// ---------------
@ -922,7 +922,7 @@
}, as.opt), acks = 0, stun = as.stun;
if((tmp = cat.root.stun) && --tmp._ === 0){ delete cat.root.stun }
(tmp = function(){ // this is not official yet, but quick solution to hack in for now.
setTimeout.each(Object.keys(stun||''), function(cb){if(cb = stun[cb]){cb()}});
setTimeout.each(Object.keys(stun||''), function(cb){if(cb = stun[cb]){cb()}}); // Any perf reasons to CPU schedule this .keys( ?
}).hatch = tmp; // this is not official yet ^
(as.via._).on('out', {put: as.out = as.graph, opt: as.opt, '#': ask, _: tmp});
}
@ -1023,29 +1023,29 @@
at.ack = 0; // so can resubscribe.
if(tmp = cat.next){
if(tmp[at.get]){
obj_del(tmp, at.get);
delete tmp[at.get];
} else {
}
}
if(tmp = cat.ask){
obj_del(tmp, at.get);
delete tmp[at.get];
}
if(tmp = cat.put){
obj_del(tmp, at.get);
delete tmp[at.get];
}
if(tmp = at.soul){
obj_del(cat.root.graph, tmp);
delete cat.root.graph[tmp];
}
if(tmp = at.map){
obj_map(tmp, function(at){
Object.keys(tmp).forEach(function(i,at){ at = tmp[i]; //obj_map(tmp, function(at){
if(at.link){
cat.root.$.get(at.link).off();
}
});
}
if(tmp = at.next){
obj_map(tmp, function(neat){
Object.keys(tmp).forEach(function(i,neat){ neat = tmp[i]; //obj_map(tmp, function(neat){
neat.$.off();
});
}
@ -1228,7 +1228,7 @@
if(!peer && mesh.way){ return mesh.way(msg) }
if(!peer || !peer.id){
if(!Object.plain(peer || opt.peers)){ return false }
var P = opt.puff, ps = opt.peers, pl = Object.keys(peer || opt.peers || {});
var P = opt.puff, ps = opt.peers, pl = Object.keys(peer || opt.peers || {}); // TODO: .keys( is slow
;(function go(){
var S = +new Date;
//Type.obj.map(peer || opt.peers, each); // in case peer is a peer list.
@ -1390,7 +1390,7 @@
root.on('hi', function(peer, tmp){ this.to.next(peer);
if(!(tmp = peer.url) || !gets[tmp]){ return } delete gets[tmp];
if(opt.super){ return } // temporary (?) until we have better fix/solution?
setTimeout.each(Object.keys(root.next), function(soul){ var node = root.next[soul];
setTimeout.each(Object.keys(root.next), function(soul){ var node = root.next[soul]; // TODO: .keys( is slow
tmp = {}; tmp[soul] = root.graph[soul]; tmp = String.hash(tmp); // TODO: BUG! This is broken.
mesh.say({'##': tmp, get: {'#': soul}}, peer);
});

View File

@ -25,11 +25,10 @@
var S = +new Date;
var souls = Object.keys(root.graph||empty);
var toss = Math.ceil(souls.length * 0.01);
//var S = +new Date;
Gun.list.map(souls, function(soul){
if(--toss < 0){ return }
setTimeout.each(souls, function(soul){
if(--toss < 0){ return 1 }
root.$.get(soul).off();
});
},0,99);
root.dup.drop(1000 * 9); // clean up message tracker
console.STAT && console.STAT(S, +new Date - S, 'evict');
}

View File

@ -41,9 +41,9 @@ Gun.on('opt', function(root){
stats.cpu = process.cpuUsage() || {};
stats.cpu.loadavg = os.loadavg();
stats.peers = {};
stats.peers.count = Object.keys(root.opt.peers||{}).length;
stats.peers.count = Object.keys(root.opt.peers||{}).length; // TODO: .keys( is slow
stats.node = {};
stats.node.count = Object.keys(root.graph||{}).length;
stats.node.count = Object.keys(root.graph||{}).length; // TODO: .keys( is slow
stats.all = all;
var dam = root.opt.mesh;
if(dam){
@ -58,16 +58,18 @@ Gun.on('opt', function(root){
}
console.STAT && console.STAT(S, +new Date - S, 'stats');
S = +new Date;
fs.writeFile(__dirname+'/../stats.'+root.opt.file, JSON.stringify(stats, null, 2), function(err){ console.STAT && console.STAT(S, +new Date - S, 'stats stash') });
JSON.stringifyAsync(stats, function(err, raw){ if(err){ return }
fs.writeFile(__dirname+'/../stats.'+root.opt.file, raw, function(err){ console.STAT && console.STAT(S, +new Date - S, 'stats stash') });
});
stats.over = S;
stats.gap = {};
exec("top -b -n 1", function(err, out){ out && fs.writeFile(__dirname+'/../stats.top.'+root.opt.file, out, noop) });
}, 1000 * 15);
Object.keys = Object.keys || function(o){ return Gun.obj.map(o, function(v,k,t){t(k)}) }
});
var exec = require("child_process").exec, noop = function(){};
require('./yson');
var log = Gun.log, all = {}, max = 1000;
Gun.log = console.STAT = function(a,b,c,d){

View File

@ -4,7 +4,7 @@ Gun.on('create', function(root){
if(Gun.TESTING){ root.opt.file = 'radatatest' }
this.to.next(root);
var opt = root.opt, empty = {}, u;
if(false === opt.radisk){ return }
if(false === opt.rad || false === opt.radisk){ return }
var Radisk = (Gun.window && Gun.window.Radisk) || require('./radisk');
var Radix = Radisk.Radix;
var dare = Radisk(opt), esc = String.fromCharCode(27);

73
nts.js
View File

@ -1,49 +1,40 @@
;(function(){
// NOTE: While the algorithm is P2P,
// the current implementation is one sided,
// only browsers self-modify, servers do not.
// Need to fix this! Since WebRTC is now working.
var env;
if(typeof global !== "undefined"){ env = global }
if(typeof window !== "undefined"){ var Gun = (env = window).Gun }
else {
if(typeof require !== "undefined"){ var Gun = require('./gun') }
}
var Gun = (typeof window !== "undefined")? window.Gun : require('./gun');
Gun.on('opt', function(ctx){
this.to.next(ctx);
if(ctx.once){ return }
ctx.on('in', function(at){
if(!at.nts && !at.NTS){
return this.to.next(at);
}
if(at['@']){
(ask[at['@']]||noop)(at);
Gun.on('create', function(root){ // switch to DAM, deprecated old
var opt = root.opt, mesh = opt.mesh;
if(!mesh){ return }
var asks = {};
mesh.hear['nts'] = function(msg, peer){
if(msg.nts){
(asks[msg['@']]||noop)(msg);
return;
}
if(env.window){
return this.to.next(at);
}
this.to.next({'@': at['#'], nts: Gun.time.is()});
mesh.say({dam: 'nts', nts: Gun.state(), '@': msg['#']}, peer);
}
var peers = 0;
root.on('hi', function(peer){ this.to.next(peer);
peers++;
setTimeout(function ping(){
var NTS = {}, ack = String.random(3), msg = {'#': ack, dam: 'nts'};
NTS.start = Gun.state();
asks[ack] = function(msg){
NTS.end = Gun.state();
delete asks[ack];
NTS.latency = (NTS.end - NTS.start)/2;
if(!msg.nts){ return }
NTS.calc = NTS.latency + msg.nts;
NTS.step = (NTS.end - NTS.calc)/2;
Gun.state.drift -= NTS.step * (1/(peers||1));
NTS.next = Math.min(2e4, Math.max(250, 150000 / Math.abs((NTS.end - NTS.calc)||1)));
console.log("I am now", Gun.state(), "they are", NTS.calc, "time sync in", NTS.next/1000, 'sec.');
setTimeout(ping, NTS.next); // Thanks @finwo ! https://discord.com/channels/612645357850984470/612645357850984473/755334349699809300
}
mesh.say(msg, peer);
}, 1);
});
var ask = {}, noop = function(){};
if(!env.window){ return }
Gun.state.drift = Gun.state.drift || 0;
setTimeout(function ping(){
var NTS = {}, ack = Gun.text.random(), msg = {'#': ack, nts: true};
NTS.start = Gun.state();
ask[ack] = function(at){
NTS.end = Gun.state();
Gun.obj.del(ask, ack);
NTS.latency = (NTS.end - NTS.start)/2;
if(!at.nts && !at.NTS){ return }
NTS.calc = NTS.latency + (at.NTS || at.nts);
Gun.state.drift -= (NTS.end - NTS.calc)/2;
setTimeout(ping, 1000);
}
ctx.on('out', msg);
}, 1);
root.on('bye', function(peer){ --peers; this.to.next(peer) });
});
// test by opening up examples/game/nts.html on devices that aren't NTP synced.
}());