vox-core
Version:
Runtime de aplicaciones multiplataforma
282 lines (227 loc) • 4.8 kB
JavaScript
var CSType= core.org.voxsoftware.Lpr.Type;
var InvocationError= core.org.voxsoftware.Lpr.InvocationException;
var ipc= module.exports= function(){
this.callbacks={};
this.parents={};
if(ipc.count>=10)
throw new core.System.OverflowException("No se pueden abrir más de 10 canales de comunicación")
this.init();
this.commandid=0;
this.bufA="";
}
ipc.count=0
/*
var os= require("os");
var windows=os.platform()=="win32";
*/
// Este método debe sobreescrito: override ..
ipc.prototype.spawn= function(){
throw new core.System.NotImplementedException("")
}
ipc.prototype.init=function(){
var p,self= this
p= this.ipc= this.spawn()
ipc.count++
p.stdin.setEncoding("utf8");
var self=this;
p.stdout.on('data', function (data) {
self.handleResponse(data);
});
p.stderr.on('data', function (data) {
console.log("Exception: ", data.toString());
});
p.on("exit", function(){
// Reiniciar el proceso ....
if(!self.closed){
self.crashed=true;
}
ipc.count--
})
p.on("error", function(err){
self.lastError= err
})
var stdin = process.openStdin();
this.$timer= setInterval(function(){
self.reviseTasks();
}, 30000);
}
ipc.prototype.close=function(){
this.closed=true;
this.ipc.kill();
this.ipc= null;
clearInterval(this.$timer);
}
ipc.prototype.createobj= function(objectid,typename,task){
var type=CSType.get(this.manager, typename);
var task1= type.loadMembers() // Si es task significa que debe cargar los miembros ...
var obj= new type(objectid)
if(task1){
task1.beforeExpose(function(){
task1.result= obj
})
task.beforeExpose(function(){
task.result= obj
return task1
})
}
return obj;
}
ipc.replacer= function(key, value){
if(value && typeof value==="object"){
var keys= Object.keys(value)
if(keys.length==1){
if(keys[0]==="$$byte[]"){
value= new Buffer(value["$$byte[]"],'base64')
}
else if(keys[0]==="$$datetime")
value= new Date(value["$$datetime"])
}
}
return value
}
ipc.prototype.handleResponse=function(buf){
var self=this;
var str=buf.toString("utf8");
var p=function(str){
if(!str){
return;
}
//vw.info("--IPC: ", str);
var res;
try{
res=JSON.parse(str, ipc.replacer);
}
catch(e){
return;
}
if(!res || !res.response){
return;
}
var id=res.commandid;
var f=self.callbacks[id];
if(f){
var p=self.parents[id];
self.callbacks[id] = false
self.parents[id] = false
var er,val;
if(res.error){
er= new InvocationError(null, res.error);
}
else{
val= res.isnull?null: (res.isdate?new Date(res.nativevalue) : (res.isthis?p: (res.objectid ? self.createobj(res.objectid, res.typename, f): res.nativevalue)))
}
if(f){
if(er){
f.exception=er;
}
else{
f.result=val;
}
f.finish();
}
else if(f===false){}
else{
if(self.manager.debug)
console.log("No fue suministrado una tarea asíncrona para el comando " +id);
}
}
}
if(str.indexOf("\n")<0){
self.bufA+=str;
}
else if(self.bufA.length>0){
self.bufA+=str;
str=self.bufA;
self.bufA="";
}
var lines=str.split("\n");
lines.forEach(p);
}
ipc.prototype.reviseTasks= function(){
var newobj={};
var d= new Date();
for(var id in this.callbacks){
var c= this.callbacks[id];
if(c){
if(c.executing && (d-c.date)>=60000){
c.exception= new core.VW.Clr.InvocationTimeoutException("Se agotó el tiempo de espera de respuesta");
c.finish();
}
else{
newobj[id]=c;
}
}
}
this.callbacks= newobj;
}
ipc.prototype.setTask=function(task,id){
this.callbacks[id]=task;
}
ipc.prototype.setObject=function(parent,id){
this.parents[id]=parent;
}
ipc.prototype.send=function(obj){
var task= core.VW.Task.get(arguments);
task.date= new Date();
if(this.lastError){
task.exception= this.lastError
task.finish()
}
else{
var er;
try{
var id= obj.commandid;
this.setTask(task,id);
ipc.commandid++;
var str=JSON.stringify(obj)+"\n";
if(this.crashed){
this.init();
this.crashed=false;
}
this.ipc.stdin.write(str);
}
catch(e){
er=e;
}
if(er){
task.exception=er;
task.finish();
}
}
return task;
}
ipc.prototype.processArg= function(val){
if(val instanceof Date){
val={
"type":"date",
"date": val
}
}
else if(Buffer.isBuffer(val)){
val= {
"byte[]": val.toString('base64')
}
}
else if(val instanceof CSType){
val={
"type":"object",
"value": val.CSid
}
}
else{
val= {value:val}
}
return val;
}
ipc.prototype.processArgs= function(args){
if(! (args instanceof Array)){
args=Array.prototype.slice.call(args,0, args.length);
}
if(args.length>0){
for(var i=0;i<args.length;i++){
args[i]=this.processArg(args[i]);
}
}
return args;
}
//module.exports=new ipc();