allex_masterservice
Version:
237 lines (228 loc) • 7.32 kB
JavaScript
function createFindSinkTask(execlib, sinkhunters){
'use strict';
var lib = execlib.lib,
q = lib.q,
execSuite = execlib.execSuite,
taskRegistry = execSuite.taskRegistry,
Task = execSuite.Task;
function getAcquireSinkFilter() {
return {
op: 'eq',
field: 'instancename',
value: this.task.getSinkName()
};
};
function SingleMachineRecordSinkHunter (task, level) {
sinkhunters.MachineRecordSinkHunter.call(this, task, level);
}
lib.inherit(SingleMachineRecordSinkHunter, sinkhunters.MachineRecordSinkHunter);
SingleMachineRecordSinkHunter.prototype.getAcquireSinkFilter = getAcquireSinkFilter;
function SingleLanSinkHunter (task, level) {
sinkhunters.LanSinkHunter.call(this, task, level);
}
lib.inherit(SingleLanSinkHunter, sinkhunters.LanSinkHunter);
SingleLanSinkHunter.prototype.getAcquireSinkFilter = getAcquireSinkFilter;
function NullSinkHunter () {
}
NullSinkHunter.prototype.destroy = lib.dummyFunc;
NullSinkHunter.prototype.go = lib.dummyFunc;
function FindSinkTask(prophash){
Task.call(this,prophash);
this.masterpid = prophash.masterpid || global.ALLEX_PROCESS_DESCRIPTOR.get('masterpid');
if(!this.masterpid){
throw new lib.Error('NO_MASTER_PID', 'No "masterpid" property in property hash for FindSinkTask');
}
this.sinkname = prophash.sinkname;
this.identity = prophash.identity;
this.prophash = prophash.propertyhash;
this.onSink = prophash.onSink;
this.addressinfo = prophash.addressinfo;
this.sink = null;
this.sinkrecord = null;
this.foundatlevel = null;
this.hunters = null;
this.sinkDestroyedListener = null;
this.subSinkHunter = null;
}
lib.inherit(FindSinkTask,Task);
FindSinkTask.prototype.destroy = function(){
if (this.subSinkHunter) {
this.subSinkHunter.destroy();
}
this.subSinkHunter = null;
if(this.sinkDestroyedListener){
this.sinkDestroyedListener.destroy();
}
this.sinkDestroyedListener = null;
if (this.hunters) {
lib.arryDestroyAll(this.hunters);
}
this.hunters = null;
this.foundatlevel = null;
this.sinkrecord = null;
this.sink = null;
this.addressinfo = null;
this.onSink = null;
this.prophash = null;
this.identity = null;
this.sinkname = null;
this.masterpid = null;
Task.prototype.destroy.call(this);
};
FindSinkTask.prototype.go = function(){
if(!this.onSink){
return;
}
this.log('FindSinkTask go for', this.sinkname, 'with', this.identity);
if (this.hunters) {
lib.arryDestroyAll(this.hunters);
}
this.hunters = [
new (this.addressinfo==='global' ? NullSinkHunter : sinkhunters.RegistrySinkHunter)(this,0),
new (this.addressinfo==='global' ? NullSinkHunter : SingleMachineRecordSinkHunter)(this,1),
new SingleLanSinkHunter(this,2)
];
this.hunters.forEach(function(h){
h.go();
});
};
FindSinkTask.prototype.getSinkName = function (index) {
index = index||0;
if (lib.isArray(this.sinkname)) {
var s = this.sinkname[index];
if (!s) {
console.log('What the #! is in this.sinkname?', this.sinkname, 'for index', index);
this.destroy();
return null;
}
return this.sinkname[index].name || this.sinkname[index];
}
return this.sinkname;
};
FindSinkTask.prototype.getIdentity = function (index) {
index = index || 0;
if (lib.isArray(this.sinkname)) {
if (index===this.sinkname.length-1) {
return this.identity;
}
return this.sinkname[index].identity || {};
} else {
return this.identity;
}
};
FindSinkTask.prototype.getPropertyHash = function (index) {
index = index || 0;
if (lib.isArray(this.sinkname)) {
if (index===this.sinkname.length-1) {
return this.prophash;
}
return this.sinkname[index].propertyhash || {};
} else {
return this.prophash;
}
};
FindSinkTask.prototype.isDirect = function (index) {
var si;
index = index || 0;
if (lib.isArray(this.sinkname)) {
si = this.sinkname[index];
if (!si) {
return false;
}
return si.direct;
}
return false;
};
FindSinkTask.prototype.reportSink = function(sink,level,record){
//this.log('FindSinkTask', this.sinkname, sink ? 'got' : 'lost', 'a sink at level', level, record ? 'that is '+ record.instancename : '', this.subSinkHunter ? 'with' : 'without', 'SubSinkHunter');
//console.log(process.pid, 'FindSinkTask', this.id, sink ? 'got' : 'got no', 'sink at level', level, record);
if(!sink){
//console.log('forgetting');
this.forgetSink(level);
return;
}
//console.log('talker', sink.clientuser.client.talker.type);
if(this.addressinfo){
if(this.addressinfo==='global'){
if(level===2){
//console.log('accepting');
this.acceptSink(sink,level,record);
return;
}
}else{
if(level>0){
//console.log('accepting');
this.acceptSink(sink,level,record);
return;
}
}
}else{
//console.log('accepting');
this.acceptSink(sink,level,record);
return;
}
//console.log('FindSinkTask with addressinfo', this.addressinfo, 'will reject the sink at level', level);
sink.destroy();
};
FindSinkTask.prototype.acceptSink = function (sink,level,record){
if(this.sink){
return;
}
if(this.sinkDestroyedListener){
console.trace();
console.error('cannot reattach to sink destroyed',sink);
return;
}
if (this.foundatlevel !== null && level!==this.foundatlevel) {
//console.log('destroying later');
sink.destroy();
return;
}
this.foundatlevel = level;
if (!this.sinkrecord) {
this.sinkrecord = record;
}
if (lib.isArray(this.sinkname) && !this.subSinkHunter) {
this.subSinkHunter = new sinkhunters.SubSinkHunter(this, sink, level);
} else {
lib.arryDestroyAll(this.hunters);
this.hunters = null;
//console.log('acceptSink', level);
if (sink.destroyed) {
this.sinkDestroyedListener = sink.destroyed.attach(this.forgetSink.bind(this,level));
}
this.sink = sink;
this.callbackTheSink(sink);
}
};
FindSinkTask.prototype.forgetSink = function(level){
this.log('forgetSink!', this.sinkname, 'level', level, 'foundatlevel', this.foundatlevel);
if(level === this.foundatlevel){
if (this.sinkDestroyedListener) {
this.sinkDestroyedListener.destroy();
}
this.sinkDestroyedListener = null;
this.sink = null;
this.sinkrecord = null;
this.foundatlevel = null;
if (this.subSinkHunter) {
this.subSinkHunter.destroy();
}
this.subSinkHunter = null;
this.callbackTheSink(null);
lib.runNext(this.go.bind(this));
}
};
FindSinkTask.prototype.callbackTheSink = function (sink) {
if (!this.onSink) {
this.destroy();
}
var onsinkret = this.onSink(sink);
if (onsinkret === true) {
this.destroy();
}
};
FindSinkTask.prototype.compulsoryConstructionProperties = ['sinkname','onSink'];
return FindSinkTask;
}
module.exports = createFindSinkTask;