Permalink
Browse files

fix some process write cache bug

  • Loading branch information...
1 parent 0b5090c commit 64a072edd4c9437d25c5a2ceaeeac88a10603957 弈轩 committed Sep 18, 2012
Showing with 293 additions and 5 deletions.
  1. +2 −2 Makefile
  2. +15 −2 lib/iservice.js
  3. +154 −0 lib/tool.js
  4. +1 −0 test/api.test.js
  5. +6 −0 test/iservice.test.js
  6. +115 −1 test/tool.test.js
View
@@ -2,12 +2,12 @@ JSCOVERAGE = ./node_modules/visionmedia-jscoverage/jscoverage
test:
@npm install
- @./node_modules/mocha/bin/mocha --reporter spec --timeout 5000 test/*.js
+ @./node_modules/mocha/bin/mocha --reporter spec --timeout 8000 test/*.js
cov:
@npm install
-mv lib lib.bak && $(JSCOVERAGE) lib.bak lib
- -./node_modules/mocha/bin/mocha --reporter html-cov --timeout 5000 --ignore-leaks test/*.js > ./coverage.html
+ -./node_modules/mocha/bin/mocha --reporter html-cov --timeout 8000 --ignore-leaks test/*.js > ./coverage.html
-rm -rf lib && mv lib.bak lib
.PHONY: test
View
@@ -30,6 +30,7 @@ exports.create = function (options) {
'token' : '',
'cache' : __dirname + '/../run/cache',
'uuid' : process.pid,
+ 'useold' : true,
};
for (var i in options) {
_options[i] = options[i];
@@ -84,14 +85,26 @@ exports.create = function (options) {
*/
var _caches = {};
+ if (_options.useold) {
+ setTimeout(function () {
+ var copy = false;
+ try {
+ fs.statSync(_options.cache + '/' + process.pid);
+ } catch (e) {
+ copy = true;
+ }
+ Tool.dump(_options.cache, copy);
+ }, 5000);
+ }
+
/* {{{ public function get() */
_me.get = function (key, callback) {
key = Tool.normalize('/' + key);
if (_caches[key]) {
return callback(null, _caches[key].data, _caches[key].meta);
}
- var fna = Tool.normalize(Util.format('%s/%s/%s.zk', _options.cache, _options.root, key));
+ var fna = Tool.normalize(Util.format('%s/%d/%s/%s.zk', _options.cache, process.pid, _options.root, key));
fs.readFile(fna, 'utf-8', function (error, data) {
if (error) {
return callback(Tool.iError('NotFound', error));
@@ -154,7 +167,7 @@ exports.create = function (options) {
}
var dir = Tool.clean(Tool.normalize(Util.format(
- '/%s/%s/%s', _options.cache, _options.root, root)), 2);
+ '/%s/%d/%s/%s', _options.cache, process.pid, _options.root, root)), 2);
var evt = Events.create(function (error) {
if (!error) {
View
@@ -2,6 +2,7 @@ var fs = require('fs');
var Path = require('path');
var Util = require('util');
var exec = require('child_process').exec;
+var Events = require(__dirname + '/events.js');
/*{{{ clean() */
function clean(str, mode){
@@ -90,3 +91,156 @@ function iError(name, error) {
exports.iError = iError;
/*}}}*/
+/*{{{ dump() */
+function dump(dir, copy, callback){
+ if (copy) {
+ getPids(function (err, pids) {
+ if (err) {
+ callback && callback(err);
+
+ } else {
+ var arr = getSorted(pids);
+ if (!arr || arr.length === 0) {
+ callback && callback(new Error('no old config'));
+ return;
+ }
+ var chosen = arr.shift();
+ exec('cp -r ' + dir + '/' + chosen.path + ' ' + dir + '/' + process.pid, function (error, stdout, stderr) {
+ if (err) {
+ callback && callback(err);
+
+ } else {
+ if (isMin(pids, process.pid)) {
+ deleteFolders(arr, function (err) {
+ callback && callback(err);
+ });
+ return;
+ }
+ callback && callback();
+ }
+ });
+
+ }
+ });
+
+ } else {
+ getPids(function (err, pids) {
+ if (err) {
+ callback && callback(err);
+ return;
+ }
+ if (isMin(pids, process.pid)) {
+ var arr = getSorted(pids);
+ arr.shift();
+ deleteFolders(arr, function (err) {
+ callback && callback(err);
+ });
+ }
+ callback && callback();
+ });
+ }
+
+ /*{{{ deleteFolders() */
+ function deleteFolders(arr, callback){
+ var arr2 = [];
+ for (var i = 0; i < arr.length; i++) {
+ arr2.push(dir + '/' + arr[i].path);
+ }
+ if (arr2.length > 0) {
+ exec('rm -rf ' + arr2.join(' '), function (error, stdout, stderr) {
+ callback(error);
+ });
+ }
+ }
+ /*}}}*/
+
+ /*{{{ getSorted() */
+ function getSorted(pids){
+ var folders = fs.readdirSync(dir);
+ var arr = [];
+ for (var idx = 0; idx < folders.length; idx++) {
+ if ((fs.statSync(dir + '/' + folders[idx]).isDirectory()) && (!contain(pids, folders[idx]))) {
+ arr.push({
+ path : folders[idx],
+ mtime : fs.statSync(dir + '/' + folders[idx]).mtime.valueOf()
+ });
+ }
+ }
+
+ var sorted = arr.sort(function (a, b) {
+ if (a.mtime > b.time) {
+ return 1;
+ } else if (a.mtime === b.time) {
+ if (a.path > b.path) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ });
+
+ return sorted;
+ }
+ /*}}}*/
+
+ /*{{{ isMin() */
+ var isMin = function (arr, one) {
+ for (var i = 0;i < arr.length; i++) {
+ if (parseInt(arr[i], 10) < parseInt(one, 10)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /*}}}*/
+
+}
+exports.dump = dump;
+/*}}}*/
+
+/*{{{ getPids() */
+function getPids(callback){
+ var pid = process.pid;
+ var command = 'ps aux | grep %d | awk \'{if ($2 == %d) {print $0}}\' | ' +
+ 'awk \'{val = ""; idx = 0; while (idx <= NF) {if (idx > 10) {val = val" "$idx;} idx++;} print(val)}\'';
+ exec(Util.format(command, pid, pid), function (error, stdout, stderr) {
+ if (error) {
+ callback(error);
+ return
+ }
+ command = 'ps aux | grep \'%s\' | grep -v grep | awk \'{print $2}\'';
+ var c = Util.format(command, stdout.split('\n').shift().substr(1));
+ exec(c, function (error, stdout, stderr) {
+ if (error) {
+ callback(error);
+ return;
+ }
+ var arr = stdout.split('\n');
+ var res = [];
+ for (var i = 0; i < arr.length; i++) {
+ arr[i] && res.push(arr[i]);
+ }
+ callback(null, res);
+ });
+ });
+}
+exports.getPids = getPids;
+/*}}}*/
+
+/*{{{ contain() */
+function contain(arr, one){
+ if (!Array.isArray(arr)) {
+ return false;
+ }
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] === one) {
+ return true;
+ }
+ }
+ return false;
+}
+exports.contain = contain;
+/*}}}*/
+
View
@@ -9,6 +9,7 @@ var Client = require(__dirname + '/../').init({
,'token' : ''
,'cache' : __dirname + '/run/cache'
,'uuid' : 'apitest'
+ ,'useold' : false
});
describe('client api', function () {
View
@@ -80,13 +80,15 @@ var http = require('http').createServer(function (req, res) {
describe('iservice connect interface', function () {
+ /*{{{ beforeEach() */
beforeEach(function (done) {
var cmd = '/bin/rm -rf "' + __dirname + '/run/cache"';
require('child_process').exec(cmd, {}, function (error) {
should.ok(!error);
done();
});
});
+ /*}}}*/
/* {{{ client object */
var client = require(__dirname + '/../lib/iservice.js').create({
@@ -95,6 +97,7 @@ describe('iservice connect interface', function () {
'token' : 'unittest',
'cache' : __dirname + '/run/cache',
'uuid' : '{PID}',
+ 'useold' : false
});
/* }}} */
@@ -225,9 +228,12 @@ describe('iservice connect interface', function () {
/* {{{ should_client_watch_works_fine() */
it('should_client_watch_works_fine', function (done) {
var num = 0;
+ var ok = false;
client.watch('/aa', 10, function (error, data) {
+ if (ok) {return;}
should.ok(!error);
if ((++num) === 2) {
+ ok = true;
done();
}
});
Oops, something went wrong.

0 comments on commit 64a072e

Please sign in to comment.