Browse Source

Merge pull request #101 from pbca26/master

cache api
all-modes
pbca26 8 years ago
committed by GitHub
parent
commit
514c87b1ba
  1. 1
      main.js
  2. 275
      routes/cache.js
  3. 4
      routes/shepherd.js

1
main.js

@ -354,6 +354,7 @@ function createWindow (status) {
return new Promise(function(resolve, reject) {
console.log('Closing Main Window...');
shepherd.dumpCacheBeforeExit();
shepherd.quitKomodod();
// if komodod is under heavy load it may not respond to cli stop the first time
setInterval(function() {

275
routes/cache.js

@ -3,63 +3,91 @@ const fs = require('fs-extra'),
async = require('async');
var cache = {};
var inMemCache;
var inMemPubkey;
cache.setVar = function(variable, value) {
cache[variable] = value;
}
/*
* cache data is dumped to disk before app quit or after cache.one call is finished
*/
cache.dumpCacheBeforeExit = function() {
if (inMemCache) {
console.log('dumping cache before exit');
fs.writeFileSync(cache.iguanaDir + '/shepherd/cache-' + inMemPubkey + '.json', JSON.stringify(inMemCache), 'utf8');
}
}
cache.get = function(req, res, next) {
var pubkey = req.query.pubkey;
const pubkey = req.query.pubkey;
if (pubkey) {
if (fs.existsSync(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json')) {
fs.readFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', 'utf8', function (err, data) {
if (err) {
var errorObj = {
'msg': 'error',
'result': err
};
inMemPubkey = pubkey;
res.end(JSON.stringify(errorObj));
} else {
try {
var parsedJSON = JSON.parse(data),
successObj = {
'msg': 'success',
'result': parsedJSON
};
res.end(JSON.stringify(successObj));
} catch (e) {
console.log(e);
if (e.toString().indexOf('at position') > -1) {
const errorPos = e.toString().split(' ');
//console.log(errorPos[errorPos.length - 1]);
//JSON.parse(data.substring(0, errorPos[errorPos.length - 1]));
console.log('JSON error ---> ' + data.substring(errorPos[errorPos.length - 1] - 20, errorPos[errorPos.length - 1] + 20) + ' | error sequence: ' + data.substring(errorPos[errorPos.length - 1], errorPos[errorPos.length - 1] + 1));
console.log('attempting to recover JSON data');
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', data.substring(0, errorPos[errorPos.length - 1]), function(err) {
var successObj = {
'msg': 'success',
'result': data.substring(0, errorPos[errorPos.length - 1])
};
res.end(JSON.stringify(successObj));
});
if (!inMemCache) {
console.log('serving cache from disk');
if (fs.existsSync(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json')) {
fs.readFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', 'utf8', function (err, data) {
if (err) {
const errorObj = {
'msg': 'error',
'result': err
};
res.end(JSON.stringify(errorObj));
} else {
try {
const parsedJSON = JSON.parse(data),
successObj = {
'msg': 'success',
'result': parsedJSON
};
inMemCache = parsedJSON;
res.end(JSON.stringify(successObj));
} catch (e) {
console.log('JSON parse error while reading cache data from disk:');
console.log(e);
if (e.toString().indexOf('at position') > -1) {
const errorPos = e.toString().split(' ');
console.log('JSON error ---> ' + data.substring(errorPos[errorPos.length - 1] - 20, errorPos[errorPos.length - 1] + 20) + ' | error sequence: ' + data.substring(errorPos[errorPos.length - 1], errorPos[errorPos.length - 1] + 1));
console.log('attempting to recover JSON data');
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', data.substring(0, errorPos[errorPos.length - 1]), function(err) {
const successObj = {
'msg': 'success',
'result': data.substring(0, errorPos[errorPos.length - 1])
};
inMemCache = JSON.parse(data.substring(0, errorPos[errorPos.length - 1]));
res.end(JSON.stringify(successObj));
});
}
}
}
}
});
});
} else {
const errorObj = {
'msg': 'error',
'result': 'no file with handle ' + pubkey
};
res.end(JSON.stringify(errorObj));
}
} else {
var errorObj = {
'msg': 'error',
'result': 'no file with handle ' + pubkey
const successObj = {
'msg': 'success',
'result': inMemCache
};
res.end(JSON.stringify(errorObj));
res.end(JSON.stringify(successObj));
}
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no pubkey provided'
};
@ -69,20 +97,20 @@ cache.get = function(req, res, next) {
}
cache.groomGet = function(req, res, next) {
var _filename = req.query.filename;
const _filename = req.query.filename;
if (_filename) {
if (fs.existsSync(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json')) {
fs.readFile(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json', 'utf8', function (err, data) {
if (err) {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': err
};
res.end(JSON.stringify(errorObj));
} else {
var successObj = {
const successObj = {
'msg': 'success',
'result': data ? JSON.parse(data) : ''
};
@ -91,7 +119,7 @@ cache.groomGet = function(req, res, next) {
}
});
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no file with name ' + _filename
};
@ -99,7 +127,7 @@ cache.groomGet = function(req, res, next) {
res.end(JSON.stringify(errorObj));
}
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no file name provided'
};
@ -109,20 +137,20 @@ cache.groomGet = function(req, res, next) {
}
cache.groomDelete = function(req, res, next) {
var _filename = req.body.filename;
const _filename = req.body.filename;
if (_filename) {
if (fs.existsSync(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json')) {
fs.unlink(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json', function(err) {
if (err) {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': err
};
res.end(JSON.stringify(errorObj));
} else {
var successObj = {
const successObj = {
'msg': 'success',
'result': 'deleted'
};
@ -131,7 +159,7 @@ cache.groomDelete = function(req, res, next) {
}
});
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no file with name ' + _filename
};
@ -139,7 +167,7 @@ cache.groomDelete = function(req, res, next) {
res.end(JSON.stringify(errorObj));
}
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no file name provided'
};
@ -149,39 +177,47 @@ cache.groomDelete = function(req, res, next) {
}
cache.groomPost = function(req, res) {
var _filename = req.body.filename,
_payload = req.body.payload;
const _filename = req.body.filename,
_payload = req.body.payload;
if (!cacheCallInProgress) {
if (_filename) {
if (!_payload) {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no payload provided'
};
res.end(JSON.stringify(errorObj));
} else {
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json', _payload, function (err) {
if (err) {
var errorObj = {
'msg': 'error',
'result': err
};
if (inMemCache) {
inMemCache = JSON.parse(_payload);
res.end(JSON.stringify(errorObj));
} else {
var successObj = {
'msg': 'success',
'result': 'done'
};
console.log('appending groom post to in mem cache');
} else {
console.log('appending groom post to on disk cache');
res.end(JSON.stringify(successObj));
}
});
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + _filename + '.json', _payload, function (err) {
if (err) {
const errorObj = {
'msg': 'error',
'result': err
};
res.end(JSON.stringify(errorObj));
} else {
const successObj = {
'msg': 'success',
'result': 'done'
};
res.end(JSON.stringify(successObj));
}
});
}
}
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no file name provided'
};
@ -189,7 +225,7 @@ cache.groomPost = function(req, res) {
res.end(JSON.stringify(errorObj));
}
} else {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'another job is in progress'
};
@ -199,11 +235,43 @@ cache.groomPost = function(req, res) {
}
var cacheCallInProgress = false,
cacheGlobLifetime = 300; // sec
cacheGlobLifetime = 600; // sec
// TODO: reset calls' states on new /cache call start
var mock = require('./mock');
var callStack = {},
checkCallStack = function() {
var total = 0;
for (var coin in callStack) {
total =+ callStack[coin];
}
if (total / Object.keys(callStack).length === 1) {
cache.dumpCacheBeforeExit();
/*fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', JSON.stringify(inMemCache), function(err) {
if (err) {
return console.log(err);
}
console.log('file ' + cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json is updated');
});*/
cacheCallInProgress = false;
cache.io.emit('messages', {
'message': {
'shepherd': {
'method': 'cache-one',
'status': 'done',
'resp': 'success'
}
}
});
// add timestamp to cache file
// writeCache(Date.now());
}
};
/*
* type: GET
* params: userpass, pubkey, coin, address, skip
@ -213,12 +281,19 @@ cache.one = function(req, res, next) {
cacheCallInProgress = false;
}
if (cacheCallInProgress) {
checkCallStack();
}
if (!cacheCallInProgress) {
cache.dumpCacheBeforeExit();
fs.readFile(cache.iguanaDir + '/shepherd/cache-' + req.query.pubkey + '.json', 'utf8', function (err, data) {
if (data) {
inMemCache = JSON.parse(data);
data = data.replace('waiting', 'failed');
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + req.query.pubkey + '.json', data, function(err) {
});
/*fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + req.query.pubkey + '.json', data, function(err) {
});*/
cache.dumpCacheBeforeExit();
}
});
// TODO: add check to allow only one cache call/sequence in progress
@ -244,7 +319,8 @@ cache.one = function(req, res, next) {
outObj.timestamp = timeStamp;
}
fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', JSON.stringify(outObj), function(err) {
inMemCache = outObj;
/*fs.writeFile(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', JSON.stringify(outObj), function(err) {
if (err) {
return console.log(err);
}
@ -253,30 +329,7 @@ cache.one = function(req, res, next) {
if (timeStamp) {
console.log('file ' + cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json is timestamped');
}
});
},
callStack = {},
checkCallStack = function() {
var total = 0;
for (var coin in callStack) {
total =+ callStack[coin];
}
if (total / Object.keys(callStack).length === 1) {
cacheCallInProgress = false;
cache.io.emit('messages', {
'message': {
'shepherd': {
'method': 'cache-one',
'status': 'done',
'resp': 'success'
}
}
});
// add timestamp to cache file
// writeCache(Date.now());
}
});*/
},
checkTimestamp = function(dateToCheck) {
var currentEpochTime = new Date(Date.now()) / 1000,
@ -286,12 +339,13 @@ cache.one = function(req, res, next) {
},
internalError = false;
inMemPubkey = pubkey;
callStack[coin] = 1;
console.log(callsArray);
console.log('iguana core port ' + iguanaCorePort);
if (!sessionKey) {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no session key provided'
};
@ -301,7 +355,7 @@ cache.one = function(req, res, next) {
}
if (!pubkey) {
var errorObj = {
const errorObj = {
'msg': 'error',
'result': 'no pubkey provided'
};
@ -313,7 +367,6 @@ cache.one = function(req, res, next) {
console.log('cache-one call started');
function fixJSON(data) {
console.log(data);
if (data && data.length) {
try {
var parsedJSON = JSON.parse(data);
@ -338,9 +391,13 @@ cache.one = function(req, res, next) {
}
if (fs.existsSync(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json') && coin !== 'all') {
var _file = fs.readFileSync(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', 'utf8');
//outObj = _file ? JSON.parse(_file) : {};
outObj = fixJSON(_file);
if (inMemCache) {
outObj = inMemCache;
} else {
var _file = fs.readFileSync(cache.iguanaDir + '/shepherd/cache-' + pubkey + '.json', 'utf8');
//outObj = _file ? JSON.parse(_file) : {};
outObj = fixJSON(_file);
}
if (!outObj || !outObj.basilisk) {
console.log('no local basilisk info');
@ -550,8 +607,10 @@ cache.one = function(req, res, next) {
outObj.basilisk[coin].addresses = addrArray;
console.log(addrArray);
writeCache();
var addrCount = outObj.basilisk[coin].addresses ? outObj.basilisk[coin].addresses.length : 0;
const addrCount = outObj.basilisk[coin].addresses ? outObj.basilisk[coin].addresses.length : 0;
var callsArrayBTC = callsArray.length;
if (callsArray.indexOf('getbalance') > - 1) {
callsArrayBTC--;
}
@ -581,7 +640,7 @@ cache.one = function(req, res, next) {
if (addresses) {
parseAddresses(coin, addresses);
} else {
var tempUrl = 'http://' + cache.appConfig.host + ':' + cache.appConfig.iguanaCorePort /*iguanaCorePort*/ + '/api/bitcoinrpc/getaddressesbyaccount?userpass=' + sessionKey + '&coin=' + coin + '&account=*';
const tempUrl = 'http://' + cache.appConfig.host + ':' + cache.appConfig.iguanaCorePort /*iguanaCorePort*/ + '/api/bitcoinrpc/getaddressesbyaccount?userpass=' + sessionKey + '&coin=' + coin + '&account=*';
request({
url: mock ? 'http://localhost:17777/shepherd/mock?url=' + tempUrl : tempUrl,
method: 'GET'
@ -612,7 +671,7 @@ cache.one = function(req, res, next) {
});
if (coin === 'all') {
var tempUrl = 'http://' + cache.appConfig.host + ':' + /*iguanaCorePort*/ cache.appConfig.iguanaCorePort + '/api/InstantDEX/allcoins?userpass=' + sessionKey;
const tempUrl = 'http://' + cache.appConfig.host + ':' + /*iguanaCorePort*/ cache.appConfig.iguanaCorePort + '/api/InstantDEX/allcoins?userpass=' + sessionKey;
request({
url: mock ? 'http://localhost:17777/shepherd/mock?url=' + tempUrl : tempUrl,
method: 'GET'

4
routes/shepherd.js

@ -220,6 +220,10 @@ shepherd.get('/sysinfo', function(req, res, next) {
res.send(obj);
});
shepherd.dumpCacheBeforeExit = function() {
cache.dumpCacheBeforeExit();
}
var cache = require('./cache');
var mock = require('./mock');

Loading…
Cancel
Save