From fcd0acaecdcf4a47ea8e72c8350f74b9204f501c Mon Sep 17 00:00:00 2001 From: haad Date: Tue, 9 Aug 2016 14:28:56 +0200 Subject: [PATCH] Add Cache to OrbitDB --- package.json | 8 ++--- src/Cache.js | 55 +++++++++++++++++++++++++++++++++++ src/OrbitDB.js | 37 ++++++++++++++--------- test/counterdb.test.js | 15 +++++----- test/orbit-db-test-cache.json | 3 -- 5 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 src/Cache.js delete mode 100644 test/orbit-db-test-cache.json diff --git a/package.json b/package.json index 494ab1a..0f8b384 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,10 @@ "main": "src/OrbitDB.js", "dependencies": { "logplease": "^1.2.7", - "orbit-db-counterstore": "0.1.0", - "orbit-db-eventstore": "0.1.0", - "orbit-db-feedstore": "0.1.0", - "orbit-db-kvstore": "0.1.0", + "orbit-db-counterstore": "0.1.1", + "orbit-db-eventstore": "0.1.1", + "orbit-db-feedstore": "0.1.1", + "orbit-db-kvstore": "0.1.1", "socket.io-client": "^1.4.5" }, "devDependencies": { diff --git a/src/Cache.js b/src/Cache.js new file mode 100644 index 0000000..0660a2d --- /dev/null +++ b/src/Cache.js @@ -0,0 +1,55 @@ +'use strict' + +const fs = require('fs') +const path = require('path') + +let filePath +let cache = {} + +class Cache { + static set(key, value) { + return new Promise((resolve, reject) => { + cache[key] = value + if(filePath) { + // console.log("write cache:", filePath, JSON.stringify(cache, null, 2)) + fs.writeFile(filePath, JSON.stringify(cache, null, 2) + "\n", resolve) + } else { + resolve() + } + }) + } + + static get(key) { + return cache[key] + } + + static loadCache(cacheFile) { + cache = {} + return new Promise((resolve, reject) => { + // console.log("load cache:", cacheFile) + if(cacheFile) { + filePath = cacheFile + fs.exists(cacheFile, (res) => { + if(res) { + fs.readFile(cacheFile, (err, res) => { + cache = JSON.parse(res) + // console.log("cache:", cache) + resolve() + }) + } else { + // console.log("cache file doesn't exist") + resolve() + } + }) + } else { + resolve() + } + }) + } + + static reset() { + cache = {} + } +} + +module.exports = Cache diff --git a/src/OrbitDB.js b/src/OrbitDB.js index 996c763..7f32dde 100644 --- a/src/OrbitDB.js +++ b/src/OrbitDB.js @@ -8,6 +8,7 @@ const FeedStore = require('orbit-db-feedstore'); const KeyValueStore = require('orbit-db-kvstore'); const CounterStore = require('orbit-db-counterstore'); const PubSub = require('./PubSub'); +const Cache = require('./Cache'); class OrbitDB { constructor(ipfs) { @@ -54,10 +55,10 @@ class OrbitDB { const replicate = options.subscribe !== undefined ? options.subscribe : true; const store = new Store(this._ipfs, this.user.username, dbname, options); this.stores[dbname] = store; - return this._subscribe(store, dbname, replicate); + return this._subscribe(store, dbname, replicate, options); } - _subscribe(store, dbname, subscribe, callback) { + _subscribe(store, dbname, subscribe, options) { if(subscribe === undefined) subscribe = true store.events.on('data', this._onData.bind(this)) @@ -69,6 +70,11 @@ class OrbitDB { else store.loadHistory().catch((e) => logger.error(e.stack)); + Cache.loadCache(options.cacheFile).then(() => { + const hash = Cache.get(dbname) + store.loadHistory(hash).catch((e) => logger.error(e.stack)) + }) + return store } @@ -77,40 +83,43 @@ class OrbitDB { _onConnected(dbname, hash) { // console.log(".CONNECTED", dbname, hash, this.user.username); - const store = this.stores[dbname]; - store.loadHistory(hash).catch((e) => logger.error(e.stack)); + const store = this.stores[dbname] + store.loadHistory(hash).catch((e) => logger.error(e.stack)) } /* Replication request from the message broker */ _onMessage(dbname, hash) { - // console.log(".MESSAGE", dbname, hash, this.user.username); - const store = this.stores[dbname]; - store.sync(hash).catch((e) => logger.error(e.stack)); + // console.log(".MESSAGE", dbname, hash, this.user.username) + const store = this.stores[dbname] + store.sync(hash) + .then((res) => Cache.set(dbname, hash)) + .catch((e) => logger.error(e.stack)) } /* Data events */ _onWrite(dbname, hash) { // 'New entry written to database...', after adding a new db entry locally - // console.log(".WRITE", dbname, hash, this.user.username); - if(!hash) throw new Error("Hash can't be null!"); - if(this._pubsub) this._pubsub.publish(dbname, hash); + // console.log(".WRITE", dbname, hash, this.user.username) + if(!hash) throw new Error("Hash can't be null!") + if(this._pubsub) this._pubsub.publish(dbname, hash) + Cache.set(dbname, hash) } _onData(dbname, item) { // 'New database entry...', after a new entry was added to the database // console.log(".SYNCED", dbname, items.length); - this.events.emit('data', dbname, item); + this.events.emit('data', dbname, item) } _onClose(dbname) { - if(this._pubsub) this._pubsub.unsubscribe(dbname); - delete this.stores[dbname]; + if(this._pubsub) this._pubsub.unsubscribe(dbname) + delete this.stores[dbname] } _connect(hash, username, password, allowOffline) { - if(allowOffline === undefined) allowOffline = false; + if(allowOffline === undefined) allowOffline = false const readNetworkInfo = (hash) => { return new Promise((resolve, reject) => { diff --git a/test/counterdb.test.js b/test/counterdb.test.js index 1f99426..6f95960 100644 --- a/test/counterdb.test.js +++ b/test/counterdb.test.js @@ -17,6 +17,7 @@ const network = 'localhost:3333'; const username = 'testrunner'; const username2 = 'rennurtset'; const ipfsPath = '/tmp/orbittests'; +const cacheFile = path.join(process.cwd(), '/test/orbit-db-cache.json') let ipfs, ipfsDaemon; const IpfsApis = [ @@ -94,7 +95,7 @@ IpfsApis.forEach(function(ipfsApi) { .then((res) => { ipfs = res; return Promise.map([username, username2], (login) => { - return OrbitDB.connect(network, login, '', ipfs, { allowOffline: false, cacheFile: './orbit-db-cache.json' }); + return OrbitDB.connect(network, login, '', ipfs, { allowOffline: false, cacheFile: cacheFile }); }).then((clients) => { client1 = clients[0]; client2 = clients[1]; @@ -111,31 +112,31 @@ IpfsApis.forEach(function(ipfsApi) { if(client1) client1.disconnect(); if(client2) client2.disconnect(); ipfsApi.stop().then(() => { - rimraf('./orbit-db-cache.json', done) + rimraf(cacheFile, done) }); }); describe('counters', function() { it('increases a counter value', function(done) { const timeout = setTimeout(() => done(new Error('event was not fired')), 2000) - const counter = client1.counter('counter test', { subscribe: false, cacheFile: './orbit-db-cache.json' }) + const counter = client1.counter('counter test', { subscribe: false, cacheFile: cacheFile }) counter.events.on('ready', () => { Promise.map([13, 1], (f) => counter.inc(f), { concurrency: 1 }) .then(() => { - clearTimeout(timeout) assert.equal(counter.value(), 14) + clearTimeout(timeout) done() }) .catch(done) }) }); - it('creates a new counter from cached data', (done) => { + it('creates a new counter from cached data', function(done) { const timeout = setTimeout(() => done(new Error('event was not fired')), 2000) - const counter = client1.counter('counter test', { subscribe: false, cacheFile: './orbit-db-cache.json' }) + const counter = client1.counter('counter test', { subscribe: false, cacheFile: cacheFile }) counter.events.on('ready', () => { - clearTimeout(timeout) assert.equal(counter.value(), 14) + clearTimeout(timeout) done() }) }) diff --git a/test/orbit-db-test-cache.json b/test/orbit-db-test-cache.json deleted file mode 100644 index e7d819b..0000000 --- a/test/orbit-db-test-cache.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "orbit-db.test": "QmdQEoYzjGGQYTBueU6B7s6Qr19qRdxWRuj9QUiQP17NRt" -}