Skip to content
Browse files

misc:add readme.md

  • Loading branch information...
1 parent 5783816 commit 96ec5c5b2f72e6e678e2efae4e6e086a8533cd2b @piaohai piaohai committed
Showing with 608 additions and 776 deletions.
  1. +13 −0 .gitignore
  2. +0 −67 README
  3. +75 −0 README.md
  4. +43 −81 lib/commands/hash.js
  5. +25 −40 lib/commands/keys.js
  6. +10 −12 lib/commands/list.js
  7. +32 −12 lib/commands/server.js
  8. +148 −201 lib/commands/string.js
  9. +69 −97 lib/dbsync.js
  10. +20 −30 lib/rewriter/filerewriter.js
  11. +2 −3 lib/rewriter/rewriter.js
  12. +3 −4 lib/utils/queue.js
  13. +1 −1 package.json
  14. +156 −195 test/bench.js
  15. +3 −3 test/mysql.js
  16. +0 −24 test/queueTest.js
  17. +4 −4 test/synclist.js
  18. +4 −2 test/synctest.js
View
13 .gitignore
@@ -0,0 +1,13 @@
+.project
+*/node-log.log
+logs/*.log
+!.gitignore
+node_modules/*
+.project
+.settings/
+**/*.svn
+*.svn
+*.sublime-project
+*.sublime-workspace
+*.swp
+.DS_Store
View
67 README
@@ -1,67 +0,0 @@
-###README
-
-data sync module is simple sync memory data into store engine like mysql,redis,file.
-
-### import
-try {
- var DBsync = require('dbsync');
-} catch (err) {
- var DBsync = require('../');
-}
-
-#### create options
-
-/**
- * Options.
- */
-
-var options = {};
-
-/**
- * Usage information.snyc for file
- */
-//var FileRewriter = require('../lib/rewriter/filerewriter');
-//options.rewrite = new FileRewriter();
-//options.interval = 1000 * 60 * 3; //default sync timer
-
-
-### Start server
-var sync = new DBsync(this,opt) ;
-
-### register object
-var user1 = new User('hello');
-var user2 = new User('world');
-
-var key = 'hello';
-
-sync.set(key,user1,function(err,resp){
- console.log('app.js register user1 result error=' + JSON.stringify(err) + ' resp ' + JSON.stringify(resp));
-});
-
-sync.set('world',user2,function(err,resp){
- console.log('app.js register user2 result error=' + err + ' resp ' + JSON.stringify(resp));
-});
-
-sync.get(key,function(err,resp){
- console.log(' app.js get result error=' + err + ' resp ' + JSON.stringify(resp));
-});
-
-
-### notice
-
-system default sync time is 1000 * 60 * 3,
-
-if you use mysql or redis sync,you should set options.client,the file sync is default but it doesn't load in current.
-
-mysql OR mapping in this modules do not support,user should realize it self.
-
-/**
- * Usage information.snyc for mysql
- */
-//var dbclient = require('./mysql/mysql');
-//var Mysqlrewriter = require('./mysqlrewriter');
-//var opt = {};
-//opt.client = dbclient;
-//opt.rewriter = new Mysqlrewriter();
-//opt.interval = 1000 * 10;
-
View
75 README.md
@@ -0,0 +1,75 @@
+#data-sync
+data sync module is simple sync memory data into store engine like mysql,redis,file.
+
+As we known, updating data is very frequently in game application. Especial in MMORPG kind game. User game data,such as location,flood,equipment,etc. almost always change as time going. For the purpose of avoid such update action cost, we decide to keep a copy data in memory. And keep synchronized with a timer and log;
+
+Data sync can support both timer call and instance invoke for the different
+situation. Most of time the developer don't pay attention to it;
+
+Data sync also can support memory operation like NOSQL database such as
+redis,mongodb etc. most of time developer can seem as a memory database without
+transaction.
+
+Data sync features include timer sync,set,get,mset,mget,hset,hget,incr,decr,flush,merger,showdown,info,etc. and the developer can extend it very easily.
+
+##Installation
+```
+npm install data-sync
+```
+
+##Usage
+``` javascript
+
+var DBsync = require('dbsync');
+
+var opt = opts || {};
+
+var updateUser = function(dbclient,val) {
+ console.log('mock save %j',val);
+}
+
+var dbclient = {};//db connection etc;
+var id = 10001;
+var optKey = 'updateUser';
+var path = {optKey:updateUer}; //key function mapping
+opt.write = path;
+opt.client = dbclient;
+opt.interval = opts.interval || 60 * 1000;
+
+var sync = new DBsync(options) ;
+sync.exec(optKey,id,{name:'hello'});
+
+```
+
+##API
+###sync.exec(key,id,val,cb)
+Add a object to sync for timer exec call back.
+####Arguments
++ key - the key function mapping for wanted to call back,it must be unique.
++ id - object primary key for merger operation.
++ val - the object wanted to synchronized.
++ cb - the function call back when timer exec.
+
+###sync.flush(key,id,val,cb)
+immediately synchronized the memory data with out waiting timer and will remove
+waiting queue data;
+####Arguments
++ key - the key function mapping for wanted to call back,it must be unique.
++ id - object primary key for merger operation.
++ val - the object wanted to synchronized.
++ cb - the function call back when timer exec.
+
+###sync.isDone
+get the db sync status when the queue is empty,it should return true;otherwise
+return false;
+
+
+
+##Notice
+system default sync time is 1000 * 60 * 3,
+if you use mysql or redis sync,you should set options.client,the file sync is default but it doesn't load in current.
+Mysql OR mapping in this modules do not support,user should realize it self.
+
+##ADD
+for more usage detail , reading source and benchmark and test case from
+source is recommended;
View
124 lib/commands/hash.js
@@ -2,23 +2,16 @@
* Module dependencies.
*/
-var utils = require('../utils/utils')
- , string = utils.string
- , invoke = utils.invoke
- , constant = require('../utils/constant');
+var utils = require('../utils/utils');
/**
* HLEN <key>
*/
-
exports.hlen = function(key){
- var obj = this.lookup(string(key));
-
- if (!obj) {
- return 0;
- } else if ('hash' == obj.type) {
+ var obj = this.lookup(key);
+ if (!!obj && 'hash' == obj.type) {
return Object.keys(obj.val).length;
} else {
- return -1;
+ return -1;
}
};
@@ -27,15 +20,11 @@ exports.hlen = function(key){
*/
exports.hvals = function(key){
- var obj = this.lookup(string(key));
- if (!obj) {
- return null
- } else if ('hash' == obj.type) {
- return (Object.keys(obj.val).map(function(key){
- return obj.val[key];
- }));
+ var obj = this.lookup(key);
+ if (!!obj && 'hash' == obj.type) {
+ return (obj.val);
} else {
- return null;
+ return null;
}
};
@@ -44,13 +33,11 @@ exports.hvals = function(key){
*/
exports.hkeys = function(key){
- var obj = this.lookup(string(key));
- if (!obj) {
- return null;
- } else if ('hash' == obj.type) {
+ var obj = this.lookup(key);
+ if (!!obj && 'hash' == obj.type) {
return Object.keys(obj.val);
} else {
- return null;
+ return null;
}
};
@@ -59,17 +46,15 @@ exports.hkeys = function(key){
*/
(exports.hset = function(key, field, val){
- var key = string(key)
- , field = string(field)
- , obj = this.lookup(key);
+ var obj = this.lookup(key);
- if (obj && 'hash' != obj.type) return false;
- obj = obj || (this.db.data[key] = { type: 'hash', val: {} });
+ if (obj && 'hash' != obj.type) { return false;}
+ obj = obj || (this.db.data[key] = { type: 'hash', val: {} });
+
+ obj.val[field] = val;
+
+ return true;
- obj.val[field] = val;
-
- return true;
-
}).mutates = true;
/**
@@ -77,23 +62,17 @@ exports.hkeys = function(key){
*/
(exports.hmset = function(data){
- var len = data.length
- , key = string(data[0])
- , obj = this.lookup(key)
- , field
- , val;
-
- if (obj && 'hash' != obj.type) return false;;
- obj = obj || (this.db.data[key] = { type: 'hash', val: {} });
-
- for (var i = 1; i < len; ++i) {
- field = string(data[i++]);
- val = data[i];
- obj.val[field] = val;
- }
+ var len = data.length , key = data[0] , obj = this.lookup(key) , field , val;
+ if (obj && 'hash' != obj.type) { return false;}
+ obj = obj || (this.db.data[key] = { type: 'hash', val: {} });
+ var i = 1;
+ for (i = 1; i < len; ++i) {
+ field = data[i++];
+ val = data[i];
+ obj.val[field] = val;
+ }
+ return true;
- return true;
-
}).mutates = true;
exports.hmset.multiple = 2;
@@ -104,20 +83,13 @@ exports.hmset.skip = 1;
*/
exports.hget = function(key, field){
- var key = string(key)
- , field = string(field)
- , obj = this.lookup(key)
- , val;
+ var obj = this.lookup(key) , val;
if (!obj) {
- return null;
+ return null;
} else if ('hash' == obj.type) {
- if (val = obj.val[field]) {
- return val;
- } else {
- return null;
- }
+ return obj.val[field] || null;
} else {
- return null;
+ return null;
}
};
@@ -126,19 +98,16 @@ exports.hget = function(key, field){
*/
exports.hgetall = function(key){
- var key = string(key)
- , obj = this.lookup(key)
- , list = [];
-
- if (!obj) {
- return null;
- } else if ('hash' == obj.type) {
- for (var field in obj.val) {
+ var obj = this.lookup(key);
+ var list = [];
+ var field;
+ if (!!obj && 'hash' == obj.type) {
+ for (field in obj.val) {
list.push(field, obj.val[field]);
}
return list;
} else {
- return null;
+ return null;
}
};
@@ -147,18 +116,11 @@ exports.hgetall = function(key){
*/
exports.hexists = function(key, field){
- var key = string(key)
- , field = string(field)
- , obj = this.lookup(key);
-
- if (obj) {
- if ('hash' == obj.type) {
- var result = (field in obj.val);
- return result;
- } else {
- return false;
- }
+ var obj = this.lookup(key);
+ if (!!obj && 'hash' == obj.type) {
+ var result = (hfield in obj.val);
+ return result;
} else {
- return false;
+ return false;
}
};
View
65 lib/commands/keys.js
@@ -1,18 +1,16 @@
/**
* Module dependencies.
*/
-var utils = require('../utils/utils')
-, invoke = utils.invoke;
+var utils = require('../utils/utils');
/**
* EXPIRE <key> <seconds>
*/
exports.expire = function(key, seconds){
- var obj = this.lookup(string(key));
-
- if (obj) {
- obj.expires = Date.now() + (string(seconds) * 1000);
+ var obj = this.lookup(key);
+ if (!!obj) {
+ obj.expires = Date.now() + (seconds * 1000);
return true;
} else {
return false;
@@ -24,10 +22,9 @@ exports.expire = function(key, seconds){
*/
exports.expireat = function(key, seconds){
- var obj = this.lookup(string(key));
-
- if (obj) {
- obj.expires = +string(seconds) * 1000;
+ var obj = this.lookup(key);
+ if (!!obj) {
+ obj.expires = +seconds * 1000;
return true;
} else {
return false;
@@ -36,9 +33,8 @@ exports.expireat = function(key, seconds){
(exports.del = function(key){
- var ikey = string(key);
- if (this.lookup(ikey)) {
- delete this.db.data[ikey];
+ if (this.lookup(key)) {
+ delete this.db.data[key];
return true;
} else {
return false;
@@ -50,9 +46,8 @@ exports.expireat = function(key, seconds){
*/
exports.persist = function(key){
- var obj = this.lookup(string(key));
-
- if (obj && 'number' == typeof obj.expires) {
+ var obj = this.lookup(key);
+ if (!!obj && 'number' == typeof obj.expires) {
delete obj.expires;
return true;
} else {
@@ -65,9 +60,8 @@ exports.persist = function(key){
*/
exports.ttl = function(key){
- var obj = this.lookup(string(key));
-
- if (obj && 'number' == typeof obj.expires) {
+ var obj = this.lookup(key);
+ if (!!obj && 'number' == typeof obj.expires) {
return (Math.round((obj.expires - Date.now()) / 1000));
} else {
return 0;
@@ -79,9 +73,8 @@ exports.ttl = function(key){
*/
exports.type = function(key){
- var obj = this.lookup(string(key));
-
- if (obj) {
+ var obj = this.lookup(key);
+ if (!!obj) {
return (obj.type);
} else {
return undefined;
@@ -93,7 +86,7 @@ exports.type = function(key){
*/
exports.exists = function(key){
- return (this.lookup(string(key)));
+ return this.lookup(key);
};
/**
@@ -101,9 +94,8 @@ exports.exists = function(key){
*/
exports.randomkey = function(){
- var keys = Object.keys(this.db.data)
- , len = keys.length;
-
+ var keys = Object.keys(this.db.data);
+ var len = keys.length;
if (len) {
var key = keys[Math.random() * len | 0];
return (key);
@@ -120,18 +112,12 @@ exports.randomkey = function(){
(exports.rename = function(from, to){
var data = this.db.data;
-
+ if (from == to) { throw Error('source and destination objects are the same');}
// Fail if attempting to rename a non-existant key
- from = string(from);
- if (!this.lookup(from)) throw error('no such key');
-
- // Fail on same keys
- to = string(to);
- if (from == to) throw error('source and destination objects are the same');
-
+ if (!this.lookup(from)) {throw Error('no such key');}
// Map key val / key type
- var type = data[from].type
- , obj = data[to] = data[from];
+ var type = data[from].type;
+ var obj = data[to] = data[from];
obj.type = type;
delete data[from];
@@ -143,12 +129,11 @@ exports.randomkey = function(){
*/
exports.keys = function(pattern){
- var pattern = string(pattern)
- , keys = Object.keys(this.db.data)
- , matched = [];
+ var keys = Object.keys(this.db.data);
+ var matched = [];
// Optimize for common "*"
- if ('*' == pattern) return (keys);
+ if ('*' == pattern) { return keys;}
// Convert pattern to regexp
pattern = utils.parsePattern(pattern);
View
22 lib/commands/list.js
@@ -1,13 +1,11 @@
-var utils = require('../utils/utils')
- , string = utils.string
- , constant = require('../utils/constant');
+var utils = require('../utils/utils');
/**
* add val to list
*/
exports.sadd = function(key,val){
this.writeToAOF('sadd', [key,val]);
- var obj = this.lookup(string(key));
+ var obj = this.lookup(key);
if (!!obj) {
obj.val.push(val);
return true;
@@ -23,15 +21,15 @@ exports.sadd = function(key,val){
*/
exports.sdel = function(key,val){
this.writeToAOF('sdel', [key,val]);
- var obj = this.lookup(string(key));
+ var obj = this.lookup(key);
if (!!obj) {
- var index = obj.val.indexOf(val);
- if (index==-1) {
- return false;
- } else {
- delete obj.val[index];
- return true;
- }
+ var index = obj.val.indexOf(val);
+ if (index==-1) {
+ return false;
+ } else {
+ delete obj.val[index];
+ return true;
+ }
} else {
return false;
}
View
44 lib/commands/server.js
@@ -2,9 +2,8 @@
* Module dependencies.
*/
-var utils = require('../utils/utils')
-, invoke = utils.invoke
-, string = utils.string;
+var utils = require('../utils/utils');
+var invoke = utils.invoke;
/**
*load data from db
@@ -14,15 +13,20 @@ exports.select = function(key, val,cb){
};
/**
- * do instant
+ * instance callback function
+ *
+ * @param {String} key
+ * @param {Object} val
+ * @param {Function} cb
+ *
*/
exports.tick = function(key,val,cb){
if (this.rewriter && this.rewriter.write[key]) {
invoke(this.rewriter.write[key],this.client,val,cb);
}
};
-/*
- *
+
+/**
* flush data to db
*
*/
@@ -44,6 +48,9 @@ exports.exec = function(){
/***
* clone new object
+ *
+ * @param {Object} obj;
+ *
*/
exports.clone = function(obj){
if (obj === Object(obj)){
@@ -60,9 +67,13 @@ exports.clone = function(obj){
return null;
}
};
+
/**
*
* flush data to db
+ *
+ * @param {String} key
+ * @param {Object} val
*
*/
exports.save = function(key, val){
@@ -84,6 +95,10 @@ exports.update = function(key, val){
/**
* delete data to db
+ *
+ * @param {String} key
+ * @param {Object} val
+ *
*/
exports.delete = function(key,val){
this.save(key,val);
@@ -93,13 +108,16 @@ exports.delete = function(key,val){
* flush all data go head
*/
exports.flushAll = function(){
- if (this.rewriter)
+ if (this.rewriter) {
this.rewriter.sync(this);
+ }
};
/**
* reutrn job is done
+ *
+ *
+ *
*/
-
exports.isDone = function(){
var writerDone = true,queueLen = false,mapLen = false;
if (this.rewrite){writerDone = this.rewriter.isDone();}
@@ -107,6 +125,7 @@ exports.isDone = function(){
mapLen = (this.getMergeLength()===0);
return writerDone && queueLen && mapLen;
};
+
/**
*return the merge length
*/
@@ -146,9 +165,10 @@ exports.flushCB = function(key,val,cb){
};
/**
- * INFO
+ * get dbsync info INFO
+ *
+ *
*/
-
exports.info = function(){
var buf = ''
, day = 86400000
@@ -166,9 +186,9 @@ exports.info = function(){
};
/**
- * BGREWRITEAOF
+ * timer sync db
+ *
*/
-
exports.sync = function(){
return this.rewriter.sync();
};
View
349 lib/commands/string.js
@@ -2,212 +2,159 @@
* Module dependencies.
*/
-var utils = require('../utils/utils')
- , string = utils.string
- , constant = require('../utils/constant');
-
+var utils = require('../utils/utils');
/**
- * GET <key>
+ * GET <key> set value
+ *
+ * @param {String} key
+ *
*/
-
exports.get = function(key){
- var obj = this.lookup(string(key));
- if (!!obj)
+ var obj = this.lookup(key);
+ if (!!obj) {
return obj.val;
- else
- return null;
-};
-
-/**
- * GETSET <key> <val>
- */
-
-exports.getset = function(key, val){
- this.writeToAOF('getset', [key,val]);
- var strKey = string(key);
-
- this.db.data[strKey] = { val: val };
-
- return this.get(key);
-};
-
-/**
- * SET <key> <str>
- */
-
-(exports.set = function(key, val){
- this.writeToAOF('set', [key,val]);
- key = string(key);
- this.db.data[key] = { val: val};
- return true;
-}).mutates = true;
-
-/**
- * SETNX <key> <val>
- */
-
-(exports.setnx = function(key, val){
- key = string(key);
- if (this.lookup(key)) return false;
- this.db.data[key] = {val: val };
- return true;
-}).mutates = true;
-
-/**
- * SETEX <key> <seconds> <val>
- */
-
-(exports.setex = function(key, seconds, val){
- var key = string(key);
-
- this.db.data[key] = {
- val: val
- , expires: Date.now() + (string(seconds) * 1000)
- };
-
- return true;
-}).mutates = true;
-
-/**
- * INCR <key>
- */
-
-(exports.incr = function(key){
- var key = string(key)||'',obj = this.lookup(key);
-
- if (!obj) {
- this.db.data[key] = {val: 1 };
- return 1;
- } else {
- return ++obj.val;
- }
-}).mutates = true;
-
-/**
- * INCRBY <key> <num>
- */
-
-(exports.incrby = function(key, num){
- var key = string(key)
- , obj = this.lookup(key)
- , num = +string(num);
-
- if (isNaN(num)) throw new Error(constant.TypeError);
-
- if (!obj) {
- obj = this.db.data[key] = {val: num };
- return (obj.val);
- } else {
- return (obj.val += num);
- }
-}).mutates = true;
-
-/**
- * DECRBY <key> <num>
- */
-
-(exports.decrby = function(key, num){
- var key = string(key)
- , obj = this.lookup(key)
- , num = +string(num);
-
- if (isNaN(num)) throw new Error(constant.OutOfRange);
-
- if (!obj) {
- obj = this.db.data[key] = {val: -num };
- return (obj.val);
- } else {
- return (obj.val -= num);
- }
-}).mutates = true;
-
-/**
- * DECR <key>
- */
-
-(exports.decr = function(key){
- var key = string(key)
- , obj = this.lookup(key);
-
- if(!obj) {
- this.db.data[key] = { val: -1 };
- return -1;
- } else {
- return --obj.val;
- }
-}).mutates = true;
-
-/**
- * STRLEN <key>
- */
-
-exports.strlen = function(key){
- var key = string(key)
- , val = this.lookup(key);
- if (val) {
- return val.length;
- } else {
- return 0;
- }
-};
-
-/**
- * MGET <key>+
- */
-
-(exports.mget = function(keys){
- var len = keys.length;
- var list = [];
- for (var i = 0; i < len; ++i) {
- var obj = this.lookup(keys[i]);
- list.push(obj);
- }
- return list;
-}).multiple = 1;
-
-/**
- * MSET (<key> <val>)+
- */
-
-exports.mset = function(strs){
- var len = strs.length
- , key
- , val;
-
- for (var i = 0; i < len; ++i) {
- key = string(strs[i++]);
- this.db.data[key] = { val: strs[i] };
+ } else {
+ return null;
}
- return true;
-};
-
-exports.mset.multiple = 2;
-exports.mset.mutates = true;
-
-/**
- * MSETNX (<key> <val>)+
- */
-
-exports.msetnx = function(strs){
- var len = strs.length
- , keys = []
- , key
- , val;
+ };
- // Ensure none exist
- for (var i = 0; i < len; ++i) {
- keys[i] = key = string(strs[i++]);
- if (this.lookup(key)) return false;;
- }
+ /**
+ * GETSET <key> <val>
+ *
+ * @param {String} key
+ * @param {String} val
+ *
+ */
+ exports.getset = function(key, val){
+ this.writeToAOF('getset', [key,val]);
+ this.db.data[key] = { val: val };
+
+ return this.get(key);
+ };
- // Perform sets
- for (var i = 0; i < len; i += 2) {
- key = keys[i];
- this.db.data[key] = {val: strs[i] }
- }
-
- return true;
-};
+ /**
+ * SET db value by key
+ *
+ * @param {String} key
+ * @param {Object} val
+ */
+
+ (exports.set = function(key, val){
+ this.writeToAOF('set', [key,val]);
+ this.db.data[key] = { val: val};
+ return true;
+ }).mutates = true;
+
+
+ /**
+ * INCR <key> counter
+ *
+ * @param {String} key
+ */
+
+ (exports.incr = function(key){
+ var obj = this.lookup(key);
+
+ if (!obj) {
+ this.db.data[key] = {val: 1 };
+ return 1;
+ } else {
+ return ++obj.val;
+ }
+ }).mutates = true;
+
+ /**
+ * INCRBY <key> counter with step <num>
+ *
+ * @param {String} key
+ * @param {number} num
+ *
+ */
+ (exports.incrby = function(key, num){
+ var obj = this.lookup(key);
+ if (isNaN(num)) { throw new Error("TypeError");}
+ if (!obj) {
+ obj = this.db.data[key] = {val: num };
+ return (obj.val);
+ } else {
+ return (obj.val += num);
+ }
+ }).mutates = true;
+
+ /**
+ * DECRBY <key> <num>
+ */
+
+ (exports.decrby = function(key, num){
+ var obj = this.lookup(key);
+ if (isNaN(num)) { throw new Error(" TypoeError");}
+ if (!obj) {
+ obj = this.db.data[key] = {val: -num };
+ return (obj.val);
+ } else {
+ obj.val = obj.val-num;
+ return obj.val;
+ }
+ }).mutates = true;
+
+ /**
+ * DECR <key>
+ */
+
+ (exports.decr = function(key){
+ var obj = this.lookup(key);
+
+ if(!obj) {
+ this.db.data[key] = { val: -1 };
+ return -1;
+ } else {
+ return --obj.val;
+ }
+ }).mutates = true;
+
+ /**
+ * STRLEN <key>
+ */
+
+ exports.strlen = function(key){
+ var val = this.lookup(key);
+ if (val) {
+ return val.length;
+ } else {
+ return 0;
+ }
+ };
+
+ /**
+ * MGET <key>+
+ */
+
+ (exports.mget = function(keys){
+ var len = keys.length;
+ var list = [];
+ for (var i = 0; i < len; ++i) {
+ var obj = this.lookup(keys[i]);
+ list.push(obj);
+ }
+ return list;
+ }).multiple = 1;
+
+ /**
+ * MSET (<key> <val>)+
+ */
+
+ exports.mset = function(strs){
+ var len = strs.length
+ , key
+ , val;
+
+ for (var i = 0; i < len; ++i) {
+ key = strs[i++];
+ this.db.data[key] = { val: strs[i] };
+ }
+ return true;
+ };
+
+ exports.mset.multiple = 2;
+ exports.mset.mutates = true;
-exports.msetnx.multiple = 2;
-exports.msetnx.mutates = true;
View
166 lib/dbsync.js
@@ -2,10 +2,7 @@
* Module dependencies.
*/
-var commands = require('./commands')
-, utils = require('./utils/utils')
-,Queue = require('./utils/queue')
-, fs = require('fs');
+var commands = require('./commands'),utils = require('./utils/utils'),Queue = require('./utils/queue'),fs = require('fs');
var crypto = require('crypto');
var Rewriter = require('../lib/rewriter/rewriter');
@@ -14,56 +11,50 @@ var SyncTimer = require('../lib/timer/synctimer');
var mutate = [];
Object.keys(commands).forEach(function(cmd){
- var fn = commands[cmd];
- if (fn.mutates) mutate.push(cmd);
+ var fn = commands[cmd];
+ if (fn.mutates) {mutate.push(cmd);}
});
/**
- * Initialize a new `Database` with the given `server` and `options`.
+ * Initialize a new `DataSync` with the given `server` and `options`.
*
* Options:
*
- * `filename` Append-only file path
- * @param {Server} server
+ * `filename` Append-only file path
* @param {Object} options
*/
-var MemDatabase = module.exports = function MemDatabase(server, options) {
- options = options || {};
- if (server) {
- this.dbs = [];
- this.selectDB(0);
- this.client = options.client;
- this.aof = options.aof || false;
- this.log = options.log || console;
- this.timer = options.timer || new SyncTimer;
- this.interval = options.interval || 1000 * 60;
- this.server = server;
- this.flushQueue = new Queue();
- this.mergerMap = {};
- if (!!options.filename) {
- this.filename = options.filename;
- } else {
- var path = process.cwd() + '/logs';
- try {
- fs.mkdirSync(path);
- } catch(ex){
- }
- this.filename = path+'/dbsync.log';
- }
- this.rewriter = options.rewriter || new Rewriter(options,this);
- this.stream = fs.createWriteStream(this.filename, { flags: 'a' });
- this.timer.start(this);
- } else {
- this.data = {};
+var DataSync = module.exports = function DataSync(options) {
+ options = options || {};
+ this.dbs = [];
+ this.selectDB(0);
+ this.client = options.client;
+ this.aof = options.aof || false;
+ this.log = options.log || console;
+ this.interval = options.interval || 1000 * 60;
+ this.flushQueue = new Queue();
+ this.mergerMap = {};
+ if (!!options.filename) {
+ this.filename = options.filename;
+ } else {
+ var path = process.cwd() + '/logs';
+ try {
+ fs.mkdirSync(path);
+ } catch(ex){
}
+ this.filename = path+'/dbsync.log';
+ }
+ this.rewriter = options.rewriter || new Rewriter(options,this);
+ this.stream = fs.createWriteStream(this.filename, { flags: 'a' });
+ this.timer = options.timer || new SyncTimer();
+ this.timer.start(this);
};
/**
* Expose commands to store.
*/
-MemDatabase.prototype = commands;
+DataSync.prototype = commands;
/**
* Select database at the given `index`.
@@ -71,45 +62,27 @@ MemDatabase.prototype = commands;
* @param {Number} index
*/
-MemDatabase.prototype.selectDB = function(index){
- var db = this.dbs[index] = this.dbs[index] || new MemDatabase;
- this.db = db;
+DataSync.prototype.selectDB = function(index){
+ var db = this.dbs[index];
+ if (!db) {
+ db = {};
+ db.data = {};
+ this.dbs[index] = db;
+ }
+ this.db = db;
};
/**
- * detect the object is change
- * @param val
- * @returns {Boolean}
+ *return the first used db
+ *
+ *
*/
-MemDatabase.prototype.changed = function(val) {
- var isChanged = false;
- if (!val)
- return isChanged;
- var shasum = crypto.createHash('md5');
- var _footprint = val.footprint;
- var _flushtime = val.flushtime;
- delete val.footprint;
- delete val.flushtime;
- shasum.update(JSON.stringify(val));
- var footprint = shasum.digest('hex');
- if (_footprint!=footprint) {
- val.flushtime = Date.now();
- val.footprint = footprint;
- isChanged = true;
- } else {
- val.flushtime = _flushtime;
- val.footprint = _footprint;
- isChanged = false;
- }
- return isChanged;
-};
-
-MemDatabase.prototype.use = function() {
- this.selectDB(0);
- var db = this.dbs[0];
- var keys = Object.keys(db);
- var dbkey = keys[0];
- return db[dbkey];
+DataSync.prototype.use = function() {
+ this.selectDB(0);
+ var db = this.dbs[0];
+ var keys = Object.keys(db);
+ var dbkey = keys[0];
+ return db[dbkey];
};
/**
@@ -120,13 +93,13 @@ MemDatabase.prototype.use = function() {
* @return {Object}
*/
-MemDatabase.prototype.lookup = function(key){
- var obj = this.db.data[key];
- if (obj && 'number' == typeof obj.expires && Date.now() > obj.expires) {
- delete this.db.data[key];
- return;
- }
- return obj;
+DataSync.prototype.lookup = function(key){
+ var obj = this.db.data[key];
+ if (obj && 'number' == typeof obj.expires && Date.now() > obj.expires) {
+ delete this.db.data[key];
+ return;
+ }
+ return obj;
};
/**
@@ -136,21 +109,20 @@ MemDatabase.prototype.lookup = function(key){
* @param {Array} args
*/
-MemDatabase.prototype.writeToAOF = function(cmd, args){
- var self = this;
- if (!self.aof) {return;}
- var argc = args.length
- , op =
- '*' + (argc + 1) + '\r\n'
- + cmd + '\r\n';
-
- // Write head length
- this.stream.write(op);
-
- // Write Args
- for (var i = 0; i < argc; ++i) {
- var key = utils.string(args[i]);
- this.stream.write(key);
- this.stream.write('\r\n');
- }
+DataSync.prototype.writeToAOF = function(cmd, args){
+ var self = this;
+ if (!self.aof) {return;}
+
+ var argc = args.length;
+ var op = '*' + (argc + 1) + '\r\n' + cmd + '\r\n';
+
+ // Write head length
+ this.stream.write(op);
+ var i = 0;
+ // Write Args
+ for (i = 0; i < argc; ++i) {
+ var key = utils.string(args[i]);
+ this.stream.write(key);
+ this.stream.write('\r\n');
+ }
};
View
50 lib/rewriter/filerewriter.js
@@ -1,7 +1,6 @@
-var utils = require('../utils/utils')
- , fs = require('fs');
-var crypto = require('crypto');
+var utils = require('../utils/utils');
+var fs = require('fs');
/**
* Initialize a new AOF FileRewriter with the given `db`.
@@ -11,10 +10,10 @@ var crypto = require('crypto');
var FileRewriter = module.exports = function FileRewriter(options) {
var self = this;
- this.write = options.write || null;
+ this.write = options.write || null;
if (!!this.write) {
- this.filename = process.cwd() + '/logs/dump.db'; //+ (Math.random() * 0xfffffff | 0);
- this.streams = fs.createWriteStream(this.filename,{ flags: 'w' });
+ this.filename = process.cwd() + '/logs/dump.db'; //+ (Math.random() * 0xfffffff | 0);
+ this.streams = fs.createWriteStream(this.filename,{ flags: 'w' });
}
this.filter = options.filter || null ;
};
@@ -24,28 +23,19 @@ var FileRewriter = module.exports = function FileRewriter(options) {
*/
FileRewriter.prototype.sync = function(server){
- var db = server.use();
- for(var key in db){
- if (!!this.filter){
- if (this.filter(key)===false) continue;
- }
- var val = db[key];
- if (server.changed(val)){
- if (!!this.write)
- this.write(key, val);
- else
- this._write(key,val)
- } else {
- if (Date.now() - val.flushtime > 60 * 1000 * 60 *24){
- //TODO 一天的数据自动清理
- //this.write(key, val);
- //delete db[dbkey][key];
- }
- }
- }
- server.queue.shiftEach(function(key){
- console.log('delete ' + key);
- });
+ var db = server.use();
+ for(var key in db){
+ if (!!this.filter){
+ if (!!!this.filter(key)) { continue ; }
+ }
+ var val = db[key];
+ if (!!this.write) {
+ this.write(key, val);}
+ else {
+ this._write(key,val);}
+ }
+ server.queue.shiftEach(function(key){
+ });
//this.end();
};
@@ -80,5 +70,5 @@ FileRewriter.prototype.string = function(key, val) {
};
FileRewriter.prototype.hash = function(key, val) {
- this.string(key,val);
-};
+ this.string(key,val);
+};
View
5 lib/rewriter/rewriter.js
@@ -1,9 +1,8 @@
/**
* Module dependencies.
*/
-var utils = require('../utils/utils')
-, invoke = utils.invoke
-, string = utils.string;
+var utils = require('../utils/utils');
+var invoke = utils.invoke;
/**
* Initialize a new AOF MysqlRewriter with the given `db`.
*
View
7 lib/utils/queue.js
@@ -34,10 +34,9 @@ Queue.prototype.forEach = function (fn) {
};
Queue.prototype.shiftEach = function (fn) {
- while (this.tail.length>0) {
- var element = this.tail.shift();{
- fn(element);
- }
+ while (this.tail.length>0) {
+ var element = this.tail.shift();
+ fn(element);
}
};
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "data-sync",
- "version": "0.0.11",
+ "version": "0.0.12",
"dependencies": {
}
}
View
351 test/bench.js
@@ -1,14 +1,14 @@
// bench for data-snyc
-var MemDatabase = require('../lib/memdatabase');
+var MemDatabase = require('../lib/dbsync');
var db = null;
var assert = require('assert');
var best = {writes: 0, hwrites:0, jwrites:0, reads: 0, hreads: 0, jreads: 0 }
- , avg = {writes: 0, writesCnt: 0, hwrites: 0, hwritesCnt: 0, jwrites: 0, jwritesCnt: 0
- , reads: 0, readsCnt: 0, hreads: 0, hreadsCnt: 0, jreads:0, jreadsCnt: 0
- }
-
+, avg = {writes: 0, writesCnt: 0, hwrites: 0, hwritesCnt: 0, jwrites: 0, jwritesCnt: 0
+ , reads: 0, readsCnt: 0, hreads: 0, hreadsCnt: 0, jreads:0, jreadsCnt: 0
+}
+
var big = []
for (var i=1000; i--; ) {
big.push(i)
@@ -16,80 +16,81 @@ for (var i=1000; i--; ) {
var objects = [
JSON.stringify('tiny')
-
-, JSON.stringify('hello I am a medium sized string')
-, JSON.stringify({
- there: 'is'
- , only: 'chaos'
- , butterfly: ['says', ['there', 'is', 'only', 'chaos']]
- , pi: Math.PI
+ , JSON.stringify('hello I am a medium sized string')
+
+ , JSON.stringify({
+ there: 'is'
+ , only: 'chaos'
+ , butterfly: ['says', ['there', 'is', 'only', 'chaos']]
+ , pi: Math.PI
})
-
-, JSON.stringify({
- there: 'is'
- , only: 'chaos'
- , butterfly: ['says', ['there', 'is', 'only', 'chaos']]
- , pi: Math.PI
- , big: big
+
+ , JSON.stringify({
+ there: 'is'
+ , only: 'chaos'
+ , butterfly: ['says', ['there', 'is', 'only', 'chaos']]
+ , pi: Math.PI
+ , big: big
})
-]
+ ]
-function bench(obj, what, num, cb) {
- console.log(' obj length:', obj.length)
- console.log(' operations:', num)
- console.log('-------------------')
-
- switch (what) {
+ function bench(obj, what, num, cb) {
+ console.log(' obj length:', obj.length)
+ console.log(' operations:', num)
+ console.log('-------------------')
+ switch (what) {
case 'all':
sets(obj, num, function() {
gets(obj, num, function() {
- hsets(obj, num, function() {
+ hsets(obj, num, function() {
hgets(obj, num, function() {
- console.log('');
- cb();
- });
+ console.log('');
+ cb();
});
+ });
})
})
break
case 'sets':
sets(obj, num, function() {
- console.log('');
+ console.log('');
cb();
})
break
case 'gets':
gets(obj, num, function() {
- console.log('');
+ console.log('');
cb();
})
break
case 'hsets':
hsets(obj, num, function() {
- console.log('');
+ console.log('');
cb();
})
break
case 'hgets':
hgets(obj, num, function() {
- console.log('');
+ console.log('');
cb();
})
break
default:
cb();
break
+ }
}
-}
-function sets(obj, num, cb) {
- var done = 0
+ function sets(obj, num, cb) {
+ var done = 0
, clients = 0
, timer = new Date()
- for (var i=num; i--; ) {
- db.set(i, obj, function(err) {
- done++
+ for (var i=num; i--; ) {
+ var res = db.set(i, obj);
+ if (res) {
+ done++
+ }
if (done === num) {
var result = ( (num) / ((new Date() - timer) / 1000))
if (result > best.writes) best.writes = result
@@ -98,18 +99,19 @@ function sets(obj, num, cb) {
console.log('sets writes:', result.toFixed(2) + '/s')
cb();
}
- })
+ }
}
-}
-function gets(obj, num, cb) {
- var done = 0
+ function gets(obj, num, cb) {
+ var done = 0
, clients = 0
, timer = new Date()
- for (var i=num; i--; ) {
- db.get(i, function(err, data) {
- done++
+ for (var i=num; i--; ) {
+ var data = db.get(i);
+ if (!!data) {
+ done++
+ }
if (done === num) {
var result = ( (num) / ((new Date() - timer) / 1000))
if (result > best.reads) best.reads = result
@@ -118,18 +120,20 @@ function gets(obj, num, cb) {
console.log('gets reads:', result.toFixed(2) + '/s')
cb();
}
- })
+
+ }
}
-}
-function hsets(obj, num, cb) {
- var done = 0
+ function hsets(obj, num, cb) {
+ var done = 0
, clients = 0
, timer = new Date()
-
- for (var i=num; i--; ) {
- db.hset('hkey', i, obj, function(err) {
- done++
+
+ for (var i=num; i--; ) {
+ var res = db.hset('hkey','num',num)
+ if (!!res) {
+ done++
+ }
if (done === num) {
var result = ( (num) / ((new Date() - timer) / 1000))
if (result > best.hwrites) best.hwrites = result
@@ -138,18 +142,18 @@ function hsets(obj, num, cb) {
console.log('hkey writes:', result.toFixed(2) + '/s')
cb()
}
- })
+ }
}
-}
-function hgets(obj, num, cb) {
- var done = 0
+ function hgets(obj, num, cb) {
+ var done = 0
, clients = 0
, timer = new Date()
-
- for (var i=num; i--; ) {
- db.hget('hkey', i, function(err, data) {
- done++
+ for (var i=num; i--; ) {
+ var res = db.hget('hkey','num');
+ if (!!res) {
+ done++
+ }
if (done === num) {
var result = ( (num) / ((new Date() - timer) / 1000))
if (result > best.hreads) best.hreads = result
@@ -158,157 +162,114 @@ function hgets(obj, num, cb) {
console.log('hkey reads:', result.toFixed(2) + '/s')
cb()
}
- })
+ }
}
-}
-
-
-var scenario = [
- ['all', 1000]
-, ['all', 2000]
-, ['sets', 5000]
-, ['sets', 10000]
-, ['gets', 5000]
-, ['gets', 10000]
-, ['hsets', 5000]
-, ['hgets', 10000]
-]
+ var scenario = [ ['all', 1000] , ['all', 2000] , ['sets', 5000] , ['sets', 10000] , ['gets', 5000] , ['gets', 10000] , ['hsets', 5000] , ['hgets', 10000] ];
+ var scenarioLen = scenario.length;
-var scenarioLen = scenario.length
-
-var next = function(i, o) {
- if (i < scenarioLen) {
- bench(objects[o], scenario[i][0], scenario[i][1], function() {
- setTimeout(function() {
- next(++i, o)
- }, scenario[i][1] / 3) // give some time for the hd to breath
- })
- } else {
- o++
- if (o===objects.length) {
- console.log('---------------------')
- console.log('')
- console.log('best writes:', best.writes.toFixed(2) + '/s')
- console.log('best hkey writes:', best.hwrites.toFixed(2) + '/s')
- console.log('best reads:', best.reads.toFixed(2) + '/s')
- console.log('best hkey reads:', best.hreads.toFixed(2) + '/s')
- console.log('avg writes:', (avg.writes / avg.writesCnt).toFixed(2) + '/s')
- console.log('avg hwrites:', (avg.hwrites / avg.hwritesCnt).toFixed(2) + '/s')
- console.log('avg reads:', (avg.reads / avg.readsCnt).toFixed(2) + '/s')
- console.log('avg hreads:', (avg.hreads / avg.hreadsCnt).toFixed(2) + '/s')
- console.log('---------------------')
- console.log('')
- console.log('all done!')
+ var next = function(i, o) {
+ if (i < scenarioLen) {
+ bench(objects[o], scenario[i][0], scenario[i][1], function() {
+ setTimeout(function() {
+ next(++i, o)
+ }, scenario[i][1] / 3) // give some time for the hd to breath
+ })
} else {
- next(0, o)
+ o++
+ if (o===objects.length) {
+ console.log('---------------------')
+ console.log('')
+ console.log('best writes:', best.writes.toFixed(2) + '/s')
+ console.log('best hkey writes:', best.hwrites.toFixed(2) + '/s')
+ console.log('best reads:', best.reads.toFixed(2) + '/s')
+ console.log('best hkey reads:', best.hreads.toFixed(2) + '/s')
+ console.log('avg writes:', (avg.writes / avg.writesCnt).toFixed(2) + '/s')
+ console.log('avg hwrites:', (avg.hwrites / avg.hwritesCnt).toFixed(2) + '/s')
+ console.log('avg reads:', (avg.reads / avg.readsCnt).toFixed(2) + '/s')
+ console.log('avg hreads:', (avg.hreads / avg.hreadsCnt).toFixed(2) + '/s')
+ console.log('---------------------')
+ console.log('')
+ console.log('all done!')
+ } else {
+ next(0, o)
+ }
}
}
-}
-var consistency = function(cb) {
- var done = 0
+ var consistency = function(cb) {
+ var done = 0
, num = 100
-
- console.log('writes...')
- for (var i=num; i--; ) {
- db.set(i, '1234567890', function(err) {
- done++
- if (done===num) {
- done = 0
- console.log('reads...')
- for (var i=num; i--; ) {
- db.get(i, function(err,res) {
- done++;
- var data = res;
- assert.equal(data, '1234567890', 'Consistency error!')
- if (done===num) {
- //doesitwork(cb)
- cb();
- }
- })
+ console.log('writes...')
+ for (var i=num; i--; ) {
+ if (db.set(i, '1234567890')) {
+ done++;
+ }
+ }
+ if (done===num) {
+ done = 0
+ console.log('reads...')
+ for (var i=num; i--; ) {
+ var res = db.get(i);
+ if (!!res) {
+ done++;
+ var data = res;
+ assert.equal(data, '1234567890', 'Consistency error!')
+ if (done===num) {
+ cb();
+ }
}
}
- })
+ }
}
-}
-var doesitwork = function(cb) {
- var cnt = 0
+ var doesitwork = function(cb) {
+ var cnt = 0
, max = 6
-
- var cntincr = 0
- for (var i=50; i--; ) {
- db.incr('incr', function(err, number) {
- cntincr++
- if (cntincr == 50) {
- console.log('incr test:', number)
- cnt++
- if (cnt === max) cb()
- }
- })
- }
- var cntdecr = 0
- db.del('decr', function(err) {
+
+ var cntincr = 0
for (var i=50; i--; ) {
- db.decr('decr', function(err, number) {
- cntdecr++
- if (cntdecr == 50) {
- console.log('decr test:', number)
+ var number = db.incr('incr');
+ cntincr++
+ if (cntincr == 50) {
+ console.log('incr test:', number)
cnt++
- if (cnt === max) cb()
+ if (cnt === max) cb()
}
- })
}
- })
- db.getorsetget('getorsetget', 'ok', function(err, data) {
- cnt++
- console.log('getorsetget:', 'ok')
- if (cnt === max) cb()
- })
- db.set('getset', 'hello', function(err) {
- db.getset('getset', 'world', function(err, data) {
+ var cntdecr = 0
+ for (var i=50; i--; ) {
+ if (db.decr('decr'))
+ cntdecr++
+ }
+ if (cntdecr == 50) {
+ console.log('decr test:', number)
cnt++
- console.log('getset:', data)
- if (cnt === max) cb()
- })
- })
- db.set('getdel', 'hello', function(err) {
- db.getdel('getdel', function(err, data) {
- db.get('getdel', function(err, data2) {
- cnt++
- console.log('getdel:', data, data2)
if (cnt === max) cb()
- })
- })
- })
-
- var cntmass = 0
- for (var i=50; i--;) {
- db.set('mass', 'writes', function(err) {
- cntmass++
- if (err) throw err
- if (cntmass===50) {
- db.get('mass', function(err, data) {
- console.log('mass:', data)
- cnt++
- if (cnt === max) cb()
- })
- }
- })
+ }
+ var cntmass = 0
+ for (var i=50; i--;) {
+ if (db.set('mass', 'writes'))
+ cntmass++
+ }
+ if (cntmass===50) {
+ var data = db.get('mass');
+ console.log('mass:', data)
+ cnt++
+ if (cnt === max) cb()
+ }
+ }
+ var start = function(db) {
+ console.log('checking consistency...')
+ consistency(function() {
+ console.log('done.')
+ console.log('=====================')
+ console.log('benchmark starting...')
+ console.log('')
+ next(0, 0)
+ });
}
-}
-var start = function(db) {
- console.log('checking consistency...')
- consistency(function() {
- console.log('done.')
- console.log('=====================')
- console.log('benchmark starting...')
- console.log('')
- next(0, 0)
- });
-}
-var db = new MemDatabase(this, {});
-start(db);
+ var db = new MemDatabase();
+ start(db);
View
6 test/mysql.js
@@ -1,7 +1,7 @@
var Client = require('mysql').Client;
var client = new Client();
-client.host = '192.168.145.18';
+client.host = 'pomelo.163.com';
client.user = 'xy';
client.password = 'dev';
client.database = 'Pomelo';
@@ -9,7 +9,7 @@ client.database = 'Pomelo';
queryHero = function(limit,offset,cb){
var users = [];
var sql = 'SELECT * FROM Hero limit ? offset ? ';
- var args = [parseInt(limit),parseInt(offset)];
+ var args = [limit,offset];
client.query(sql,args,function selectCb(error, results, fields) {
if (error) {
console.log('queryHero Error: ' + error.message);
@@ -42,4 +42,4 @@ genHero = function(last,max,cb){
};
};
-exports.client = client;
+exports.client = client;
View
24 test/queueTest.js
@@ -1,24 +0,0 @@
-var Queue = require('../lib/utils/queue');
-
-var test = new Queue();
-
-console.log(test.__proto__);
-
-//test.push(1);
-//test.push(2);
-//test.push(4);
-
-test.forEach(function(vx){
- console.log(vx);
-});
-
-console.log(test);
-
-
-test.shiftEach(function(vx){
- console.log('delete ' + vx);
-});
-
-
-
-console.log(test);
View
8 test/synclist.js
@@ -7,7 +7,7 @@ updatewrite = function(client,val,cb){
if(err !== null){
console.error('write mysql failed! ' + sql + ' ' + JSON.stringify(val));
} else {
- console.info('write mysql success! flash dbok ' + sql + ' ' + JSON.stringify(val));
+ console.info('write mysql success! flash dbok ' + sql + ' ' + JSON.stringify(val));
cb();
}
});
@@ -20,9 +20,9 @@ selectUser = function(client,val,cb){
client.query(sql, args, function(err, res){
if(err !== null){
console.error('selectUser mysql failed! ' + sql + ' ' + JSON.stringify(val));
- cb(null,'-1');
+ cb(null,'-1');
} else {
- console.info('selectUser mysql success! flash dbok ' + sql + ' ' + JSON.stringify(val));
+ console.info('selectUser mysql success! flash dbok ' + sql + ' ' + JSON.stringify(val));
cb(null,res[0]['name']);
}
});
@@ -31,4 +31,4 @@ selectUser = function(client,val,cb){
var map = {};
map['updateUser'] = updatewrite;
map['selectUser'] = selectUser;
-exports.map = map;
+exports.map = map;
View
6 test/synctest.js
@@ -13,7 +13,7 @@ opt.write = map;
opt.client = dbclient;
opt.interval = 5000;
opt.aof = true;
-var sync = new MemDatabase(this,opt) ;
+var sync = new MemDatabase(opt) ;
var key = 'user_key';
var User = function User(name){
this.name = name;
@@ -25,6 +25,8 @@ user1.uid = 10003;
user1.sceneId = 1;
var resp = sync.set(key,user1);
+console.log('resp %j' , sync.get(key));
+
//sync.flush('updateUser',user1);
//sync.exec('updateUser',10003,user1);
@@ -46,4 +48,4 @@ user1.x = 999;
setInterval(function(){
console.log(' count 2 ' + sync.isDone());
-},1000);
+},1000);

0 comments on commit 96ec5c5

Please sign in to comment.
Something went wrong with that request. Please try again.