gun/shots.js
2014-03-30 15:22:49 -06:00

236 lines
7.0 KiB
JavaScript

module.exports = require('theory')
('shot',function(a){
var s3 = require(__dirname+'/gate/s3')
, store = require(__dirname+'/gate/redis');
return function(opt){
opt = opt || {};
var u, shot = {};
opt.path = opt.path || '.'
opt.batch = opt.batch || 10;
opt.throttle = opt.throttle || 15;
opt.src = opt.src || (this && this.com) || '';
opt.redis = opt.redis || {};
opt.redis.max = a.num.is(opt.redis.max)? opt.redis.max : .8;
opt.redis.Max = Math.floor(require('os').totalmem() * opt.redis.max);
opt.redis.append = a.obj(opt.redis).has('append')? opt.redis.append : true;
opt.redis.expire = opt.redis.expire || 60*15;
opt.redis.config = function(){
if(opt.redis.config.done === 0){ return }
opt.redis.config.done = 3;
var reply = function(e,r){
if(e){ return }
opt.redis.config.done -= 1;
};
if(opt.redis.max){
store.client.config('set','maxmemory',opt.redis.Max, reply);
store.client.config('set','maxmemory-policy','allkeys-lru', reply);
}
if(opt.redis.append){
store.client.config('set','appendonly','yes', reply);
}
}
opt.s3 = opt.s3 || {};
opt.s3.Bucket = a.text.is(opt.s3.bucket)? opt.s3.bucket : '';
opt.s3.bucket = a.fns.is(opt.s3.bucket)? opt.s3.bucket : function(key){
return opt.s3.Bucket || a.text(key).clip('/',0,1);
}
opt.s3.key = a.fns.is(opt.s3.key)? opt.s3.key : function(key){
if(opt.s3.Bucket){ return key }
return a.text(key).clip('/',1);
}
theory.on(a.gun.event).event(function(m, db){
return;
});
store.batch = [];
store.last = a.time.now();
store.push = function(key, score, val, cb){
store.client.zadd(key, score, val, function(e,r){
if(e){
store.clienf.zadd(key, score, val, cb);
return;
}
if(cb){ cb(e,r) }
});
}
store.add = function(m, db){
if(!m){ return }
db = '_' + (db || a(m,'where.at') || m.where);
store.push(db, a(m,'what._.#') || m.when || 0, a.text.ify(m));
}
store.del = function(m, db){
}
store.sort = function(A,B){
if(!A || !B){ return 0 }
A = A.w; B = B.w;
if(A < B){ return -1 }
else if(A > B){ return 1 }
else { return 0 }
}
store.batching = 0;
store.batched = {};
store.batch = {};
store.wait = null;
store.stay = function(key, val, cb){
store.batching += 1;
store.batch[key] = val;
(store.batched[key] = store.batched[key]||[]).push(cb);
if(opt.batch < store.batching){
return store.stay.now();
}
if(!opt.throttle){
return store.stay.now();
}
store.wait = store.wait || a.time.wait(store.stay.now, opt.throttle * 1000); // to seconds
}
store.stay.now = function(){
store.batching = 0;
a.time.stop(store.wait);
store.wait = null;
console.log('*************** chug chug chug *******************');
a.obj(store.batch).each(function(g,where){
if(!g || !where){ return }
console.log('save', where, (g && g.packageson && g.packageson._));
s3(opt.s3.bucket(where)).put(opt.s3.key(where),g,function(e,r){
a.list(store.batched[where]).each(function(cb){
if(a.fns.is(cb)){ cb(e,r) }
console.log('batch save s3 done', where);
});
delete store.batched[where];
});
});
console.log('*** end ***');
}
store.set = function(key, value, cb, fn){
opt.redis.config();
var val = a.text.is(value)? value : a.text.ify(value);
if(a.fns.is(fn)){ store.stay(key, value, fn) }
if(opt.redis.max){
store.client.set(key, val, function(e,r){
if(e){
store.clienf.setex(key, opt.redis.expire, val, cb);
return;
}
if(cb){ cb(e,r) }
});
} else {
store.client.setex(key, opt.redis.expire, val, function(e,r){
if(e){
store.clienf.setex(key, opt.redis.expire, val, cb);
return;
}
if(cb){ cb(e,r) }
});
}
}
store.get = function(key, cb){
store.clienf.get(key, function(e,r){
if(e || !r){ return store.client.get(key, cb) }
if(cb){ cb(e,r) }
});
}
shot.shell = function(where,cb,o){
if(!where){ return }
where = a.text.is(where)? where : (where.at || where);
if(!a.text.is(where)){ return }
if(a.fns.is(a.gun.clip[where])){
console.log('via memory', where);
cb(a.gun.clip[where]); // TODO: Need to delete these at some point, too!
return;
}
store.get(where, function(e,r){
if(e || !r){
return s3(opt.s3.bucket(where)).get(opt.s3.key(where),function(e,r,t){
console.log('via s3', where);
console.log(e,r, t);
if(e || !r){ return cb(null, e) }
store.set(where, (t || a.text.ify(r)));
r = a.gun(where,r);
cb(r, e);
},o);
}
console.log('via redis', where);
r = a.obj.ify(r);
r = a.gun(where,r);
cb(r);
});
}
shot.spray = function(m){
if(m && m.how){
shot.spray.action(m);
return shot;
}
if(a.fns.is(m)){
shot.spray.transform = m;
return shot.spray.action;
}
return shot.spray.action;
}
shot.spray.transform = function(g,m,d){if(d){d()}}
shot.spray.action = function(m){
console.log('spray', m);
if(!m || !m.how){ return }
var where = a.text.is(m.where)? m.where : m.where.at;
if(m.how.gun === 3){
shot.shell(m.what._['%']||where, function(g,e){
shot.pump.action(g, m, function(){ // receive custom edited copy here and send it down instead.
if(opt.src && opt.src.reply){
m.what = a.fns.is(g)? g() : {};
m.how.gun = -(m.how.gun||3);
opt.src.reply(m);
}
}, e);
});
return;
}
if(!where){ return }
store.add(m);
shot.shell(where, function(g,e){
var done = function(){
theory.on(a.gun.event+'.shot').emit(m.what,g);
g = a.fns.is(g)? g : function(){ return a.gun.clip[where] || {} }
store.set(where, g(), null, function(){ // TODO: Only save to S3 if there is a change in data after HAM.
if(opt.src && opt.src.reply){
m.when = a.num.is(a(m,'what._.#'))? m.what._['#'] : m.when;
m.how.gun = -(m.how.gun||1);
m.what = where;
m.where = null;
opt.src.reply(m);
}
});
};
done.end = function(){};
shot.spray.transform(g, m, done, e);
});
}
shot.pump = function(fn){
shot.pump.action = fn || shot.pump.action;
return shot;
}
shot.pump.action = function(g,m,d){if(d){d()}}
shot.server = function(req,res){
if(!req || !res){ return }
var b = shot.server.get(req);
if(!b || !b.b){ return }
b = a.obj.ify((b||{}).b);
if(a.obj.is(b)){ b = [b] }
if(!a.list.is(b)){ return }
//console.log('gun >>>>>>');
a.list(b).each(function(v,i){
//console.log(v);
});
//console.log('<<<<<< gun');
if(req.how && req.when && req.who && a.fns.is(res)){
req.what.body = {ok:1};
res(req);
}
return true;
}
shot.server.get = function(m){
return !a.obj.empty(a(m,'what.form'))? a(m,'what.form')
: !a.obj.empty(a(m,'what.url.query'))? a(m,'what.url.query')
: false ;
};
return shot;
}
},[__dirname+'/gun'])