Browse Source

update gundb lib

Nikolay Suslov 6 years ago
parent
commit
0f9626a437

+ 121 - 0
public/lib/gundb/lib/les.js

@@ -0,0 +1,121 @@
+;
+(function() {
+
+	//  _     _____ ____    _     
+	// | |   | ____/ ___|  (_)___ 
+	// | |   |  _| \___ \  | / __|
+	// | |___| |___ ___) | | \__ \
+	// |_____|_____|____(_)/ |___/
+	// ----------------------------
+	// LES.js (Last rEcently uSed)
+	// ----------------------------
+	// A Small, lightweight, queue-based
+	// Garbage Collector for Gun
+	// Originally By: Collin Conrad (@masterex1000)
+
+	//NOTE: set to false is running from file in YOUR code
+	var USELOCALGUN = true; 
+	
+	//NOTE: adds some debug messages
+	var DEBUG = false;
+	
+	
+	var Gun = (typeof window !== "undefined") ? window.Gun : (USELOCALGUN ? require('../gun') : require("gun"));
+	var ev = {};
+	var empty = {};
+
+	Gun.on('opt', function(root) {
+		this.to.next(root);
+		if (root.once)
+			return;
+		if (typeof process == 'undefined')
+			return
+		var mem = process.memoryUsage;
+
+		if (!mem) //exit because we are in the browser
+			return;
+
+		//Figure out the most amount of memory we can use. TODO: make configurable?
+		ev.max = parseFloat(root.opt.memory || process.env.WEB_MEMORY || 512) * 0.8;
+
+		var nodes = {}; //checks if the node already exists
+		var nodesArray = []; //used to easily sort everything and store info about the nodes
+		var memoryUpdate = 0; // last time we printed the current memory stats
+
+		var check = function() {
+			ev.used = mem().rss / 1024 / 1024; //Contains the amt. of used ram in MB
+			setTimeout(function() { // So we can handle requests etc. before we start collecting
+				GC(ev.used / ev.max); // Calculate the memory ratio, and execute the garbage collector
+			}, 1);
+		}
+		
+		setInterval(check, 1000); // set the garbage collector to run every second, TODO: make configurable
+		
+		//Executed every time a node gets modifyed
+		root.on("put", function(e) {
+			var ctime = Date.now();
+			var souls = Object.keys(e.put || empty);
+			for (var i = 0; i < souls.length; i++) {
+				enqueueNode(souls[i], ctime);
+			}
+		});
+
+		//Adds a soul the garbage collectors "freeing" queue
+		function enqueueNode(soul, ctime) {
+			if (nodes[soul] == true) { //The node already exists in the queue
+				var index = nodesArray.findIndex(function(e) {
+					return e[0] === soul;
+				});
+				if (index == -1) {
+					console.err("Something happened and the node '" + soul + "' won't get garbage collection unless the value is updated agian");
+					return;
+				} else {
+					nodesArray.splice(index, 1); // remove the existing ref.
+					nodesArray.push([soul, ctime]); // push the new instance
+				}
+			} else {
+				nodesArray.push([soul, ctime]);
+				nodes[soul] = true;
+			}
+		}
+
+		//The main garbage collecting routine
+		function GC(memRatio) {
+			var curTime = Date.now(); // get the current time
+
+			if (curTime - memoryUpdate >= 5000) {
+				console.log("|GC| %s | Current Memory Ratio: %d | Current Ram Usage %sMB | Nodes in Memory %s", new Date().toLocaleString(), round(memRatio, 2), round(ev.used, 2), Object.keys(root.graph || empty).length);
+				memoryUpdate = curTime;
+			}
+
+			var freed = 0;
+
+			while (nodesArray.length > 0) {
+				var soul = nodesArray[0][0];
+				var nts = nodesArray[0][1];
+				if (DEBUG)
+					console.log("Soul: " + soul + " | Remove Importance: " + calcRemoveImportance(nts, curTime, memRatio) +
+						" | Memory Ratio: " + memRatio + " | Time Existed: " + (curTime - nts) / 1000);
+				if (calcRemoveImportance(nodesArray[0][1], curTime, memRatio) >= 100) {
+					root.gun.get(nodesArray[0][0]).off(); //Remove the node
+					delete nodes[nodesArray[0][0]]; // remove the lookup value
+					nodesArray.splice(0, 1);
+					freed++;
+				} else
+					break;
+			}
+			if (freed > 0)
+				console.log("|GC| Removed %s nodes in %s seconds-----------------------------------------------------------------", freed, (Date.now() - curTime) * 0.001);
+		}
+
+		//Generates a number that, after it hits a threshold, the node gets removed
+		function calcRemoveImportance(timestamp, ctime, memoryUsageRatio) {
+			var time = (ctime - timestamp) * 0.001;
+			return time * 10 * (memoryUsageRatio * memoryUsageRatio)
+		}
+
+		function round(value, decimals) { //a basic rounding function
+			return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
+		}
+	});
+}());

+ 2 - 2
public/lib/gundb/nts.js

@@ -37,8 +37,8 @@
 				NTS.end = Gun.state();
 				Gun.obj.del(ask, ack);
 				NTS.latency = (NTS.end - NTS.start)/2;
-				if(!at.NTS){ return }
-				NTS.calc = NTS.latency + at.NTS;
+				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);
 			}

+ 2 - 2
public/lib/gundb/sea.js

@@ -272,7 +272,7 @@
     // This internal func returns SHA-1 hashed data for KeyID generation
     const __shim = USE('./shim')
     const subtle = __shim.subtle
-    const ossl = __shim.ossl ? __shim.__ossl : subtle
+    const ossl = __shim.ossl ? __shim.ossl : subtle
     const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b))
     module.exports = sha1hash
   })(USE, './sha1');
@@ -629,7 +629,7 @@
       try {
         // base64('base64(x):base64(y)') => Buffer(xy)
         const pb = Buffer.concat(
-          Buffer.from(pub, 'base64').toString('utf8').split(':')
+          pub.replace(/-/g, '+').replace(/_/g, '/').split('.')
           .map((t) => Buffer.from(t, 'base64'))
         )
         // id is PGPv4 compliant raw key

+ 2 - 2
public/lib/gundb/sea/index.js

@@ -62,7 +62,7 @@
         // if there is a request to read data from us, then...
         var soul = msg.get['#'];
         if(soul){ // for now, only allow direct IDs to be read.
-          if(soul !== 'string'){ return to.next(msg) } // do not handle lexical cursors.
+          if(typeof soul !== 'string'){ return to.next(msg) } // do not handle lexical cursors.
           if('alias' === soul){ // Allow reading the list of usernames/aliases in the system?
             return to.next(msg); // yes.
           } else
@@ -226,4 +226,4 @@
       to.next(msg); // pass forward any data we do not know how to handle or process (this allows custom security protocols).
     }
 
-  
+  

+ 1 - 1
public/lib/gundb/sea/sea.js

@@ -49,7 +49,7 @@
       try {
         // base64('base64(x):base64(y)') => Buffer(xy)
         const pb = Buffer.concat(
-          Buffer.from(pub, 'base64').toString('utf8').split(':')
+          pub.replace(/-/g, '+').replace(/_/g, '/').split('.')
           .map((t) => Buffer.from(t, 'base64'))
         )
         // id is PGPv4 compliant raw key

+ 1 - 1
public/lib/gundb/sea/sha1.js

@@ -2,7 +2,7 @@
     // This internal func returns SHA-1 hashed data for KeyID generation
     const __shim = require('./shim')
     const subtle = __shim.subtle
-    const ossl = __shim.ossl ? __shim.__ossl : subtle
+    const ossl = __shim.ossl ? __shim.ossl : subtle
     const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b))
     module.exports = sha1hash