mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
have NTS use DAM + fix other utils
This commit is contained in:
parent
356a971ddc
commit
bac0e5b7ed
@ -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
50
gun.js
@ -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);
|
||||
});
|
||||
|
@ -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');
|
||||
}
|
||||
|
10
lib/stats.js
10
lib/stats.js
@ -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){
|
||||
|
@ -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
73
nts.js
@ -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.
|
||||
}());
|
Loading…
x
Reference in New Issue
Block a user