You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
6.1 KiB
281 lines
6.1 KiB
module.exports = (logger, nodetable) => { |
|
|
|
|
|
let nodes = {} |
|
const CMD_DELAY = 200; |
|
|
|
let delay = (time_ms) => new Promise(resolve => { |
|
setTimeout(()=>{ |
|
resolve(); |
|
}, time_ms); |
|
}); |
|
|
|
|
|
|
|
const event = logger.getLogger('event'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
nodetable.newNode((nid, info) => { |
|
nodes[nid] = { |
|
send: (name, body, isudp) => { |
|
return nodetable.outgo(nid, { |
|
to: nid, |
|
from: "director", |
|
name: name, |
|
body: body |
|
}, isudp); |
|
}, |
|
triggers: { |
|
income: [ |
|
function(name, body){ |
|
if(name == '__getInfo'){ |
|
nodes[nid].info.localport = body.port; |
|
nodes[nid].info.localip = body.ip; |
|
nodes[nid].info.funcID = body.funcID; |
|
nodes[nid].info.HeartbeatInterval = body.HeartbeatInterval; |
|
nodes[nid].ns = body.ns; |
|
nodes[nid].LastRefreshTime = new Date().valueOf(); |
|
} |
|
}, |
|
function(name, body){ |
|
if(name == '__checkNS'){ |
|
if(!nodes[nid].rns.hasOwnProperty(body.from) || nodes[nid].rns[body.from].ip != body.ip || nodes[nid].rns[body.from].port != body.port){ |
|
nodes[nid].rns[body.from] = body; |
|
nodes[nid].rns[body.from].updated = true; |
|
} |
|
nodes[nid].rns[body.from].LastCheckTime = new Date().valueOf(); |
|
} |
|
} |
|
], |
|
connect: [], |
|
disconnect: [], |
|
restart: [], |
|
error: [] |
|
}, |
|
LastRefreshTime: 0, |
|
LastRestartTime: 0, |
|
ns: {}, |
|
rns: {}, |
|
on: (type, cb) => { |
|
nodes[nid].triggers[type].push(cb); |
|
}, |
|
restart: () => new Promise((resolve) => { |
|
let restartTime = new Date().valueOf(); |
|
let counter = 100; |
|
nodes[nid].send('__restart', ''); |
|
let timer = () => { |
|
setTimeout(()=>{ |
|
if(nodes[nid].info.LastUpTime < restartTime){ |
|
if(counter){ |
|
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
|
nodes[nid].send('__restart', ''); |
|
restartTime = new Date().valueOf(); |
|
counter = 100; |
|
} |
|
timer(); |
|
counter --; |
|
}else{ |
|
resolve(false); |
|
return; |
|
} |
|
}else{ |
|
event.info('[CMD]', '<'+nid+'>', '__restart'); |
|
resolve(true); |
|
return; |
|
} |
|
}, 300); |
|
}; |
|
timer(); |
|
}), |
|
refresh: () => new Promise((resolve) => { |
|
let startTime = new Date().valueOf(); |
|
let counter = 100; |
|
nodes[nid].send('__getInfo', ''); |
|
let timer = () => { |
|
setTimeout(async ()=>{ |
|
if(nodes[nid].LastRefreshTime < startTime){ |
|
if(counter){ |
|
if(counter == 70 || counter == 40){ |
|
nodes[nid].send('__getInfo', ''); |
|
} |
|
timer(); |
|
counter--; |
|
}else{ |
|
resolve(false); |
|
return; |
|
} |
|
}else{ |
|
await delay(CMD_DELAY) |
|
event.info('[CMD]', '<'+nid+'>', '__refresh'); |
|
resolve(true); |
|
return; |
|
} |
|
}, 300); |
|
}; |
|
timer(); |
|
}), |
|
setNS: (nsArr) => new Promise(async (resolve) => { |
|
|
|
|
|
let checkLocalNS = () => Object.keys(nodes[nid].ns).every(id => { |
|
if(nsArr.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
|
return true; |
|
}else{ |
|
return false; |
|
} |
|
}) && Object.keys(nsArr).every(id => { |
|
if(nodes[nid].ns.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
|
return true; |
|
}else{ |
|
return false; |
|
} |
|
}); |
|
|
|
|
|
|
|
if(checkLocalNS()){ |
|
resolve(true); |
|
return; |
|
} |
|
|
|
|
|
let body = {}; |
|
Object.keys(nsArr).forEach(id => { |
|
body[id] = { |
|
ip: nsArr[id].ip, |
|
port: nsArr[id].port |
|
} |
|
}); |
|
|
|
|
|
nodes[nid].send('__setNS', body); |
|
|
|
|
|
await delay(CMD_DELAY); |
|
|
|
if(checkLocalNS()){ |
|
event.info('[CMD]', '<'+nid+'>', '__setNS', JSON.stringify(Object.keys(body))); |
|
resolve(true); |
|
}else{ |
|
resolve(false); |
|
} |
|
|
|
}), |
|
checkNS: (id, ip, port) => new Promise(async (resolve) => { |
|
|
|
nodes[nid].send('__checkNS', { |
|
to: id, |
|
from: nid, |
|
ip: ip, |
|
port: port |
|
}, true); |
|
|
|
await delay(CMD_DELAY); |
|
|
|
nodes[nid].send('__checkNS', { |
|
to: id, |
|
from: nid, |
|
ip: ip, |
|
port: port |
|
},true); |
|
|
|
await delay(CMD_DELAY); |
|
|
|
event.info('[CMD]', '<'+nid+'>', '__checkNS', id); |
|
resolve(); |
|
|
|
}), |
|
setFunc: (id, func) => new Promise(async resolve => { |
|
let restartTime = new Date().valueOf(); |
|
let counter = 100; |
|
if(nodes[nid].info.funcID == id) { |
|
resolve(true); |
|
return; |
|
} |
|
nodes[nid].send('__setFunc', { |
|
func: { |
|
id: id, |
|
online: func |
|
} |
|
}); |
|
let timer = () => { |
|
setTimeout(()=>{ |
|
if(nodes[nid].info.LastUpTime < restartTime || nodes[nid].info.funcID != id){ |
|
if(counter){ |
|
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
|
nodes[nid].send('__setFunc', { |
|
func: { |
|
id: id, |
|
online: func |
|
} |
|
}); |
|
restartTime = new Date().valueOf(); |
|
//counter = 100; |
|
} |
|
timer(); |
|
counter --; |
|
}else{ |
|
resolve(false); |
|
return; |
|
} |
|
}else{ |
|
event.info('[CMD]', '<'+nid+'>', '__setFunc', id, func); |
|
resolve(true); |
|
return; |
|
} |
|
}, 300); |
|
}; |
|
timer(); |
|
}) |
|
}; |
|
nodes[nid].info = info; |
|
}); |
|
|
|
|
|
nodetable.connect((nid, info) => { |
|
nodes[nid].status = true; |
|
if(new Date().valueOf() < nodes[nid].info.LastUpTime + nodes[nid].info.HeartbeatInterval){ |
|
nodes[nid].triggers.restart.forEach(cb => { |
|
cb(); |
|
}); |
|
nodes[nid].LastRestartTime = new Date().valueOf(); |
|
event.info('[RESTART]', '<'+nid+'>', '{'+info.funcID+'}'); |
|
} |
|
nodes[nid].triggers.connect.forEach(cb => { |
|
cb(); |
|
}); |
|
event.info('[CONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
|
|
|
}); |
|
|
|
|
|
nodetable.disconnect((nid, info) => { |
|
nodes[nid].status = false; |
|
nodes[nid].triggers.disconnect.forEach(cb => { |
|
cb(); |
|
}); |
|
event.info('[DISCONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
|
}); |
|
|
|
nodetable.income((nid, info, data) => { |
|
nodes[nid].status = true; |
|
nodes[nid].triggers.income.forEach(cb => { |
|
cb(data.name, data.body); |
|
}); |
|
}); |
|
|
|
|
|
nodetable.error((nid, info) => { |
|
nodes[nid].triggers.error.forEach(cb => { |
|
cb(info.error); |
|
}); |
|
event.error('[ERROR]', '<'+nid+'>', '{'+info.funcID+'}', info.error); |
|
}); |
|
|
|
|
|
return nodes; |
|
} |