UNPKG

paraemu

Version:

An working enviroment that provides a simplified interface for developers who want to fully parallelize node execution

132 lines (114 loc) 3.65 kB
(()=>{ "use strict"; const {EventEmitter} = require('events'); const {ObjectId:{GenObjectId}, Helper:{GenRandomID, SetConstant}} = include( 'lib' ); const GEN_RANDOM_ID = GenRandomID.bind(null, 16); const DELIVERY_TIMEOUT = 30 * 1000; const DELIVERY_RESPONSE_TIMEOUT = 2 * 1000; module.exports = (groupId, taskId, jobId=null)=>{ const JOB_INST = new EventEmitter(); const JOB_ID = jobId||GEN_RANDOM_ID(); const ACTIVE_DELIVERY_POOL = {}; const PASSIVE_DELIVERY_POOL = {}; // Register constants SetConstant(JOB_INST, { jobId: JOB_ID, groupId, taskId, uniqueId: `${groupId}-${taskId}-${JOB_ID}` }); // region [ Prepare APIs for developers ] JOB_INST.__in = null; SetConstant(JOB_INST, { __emit:JOB_INST.emit.bind(JOB_INST), __dispatch:function(eventInfo, broadcast=true) { if ( typeof this.__in === "function" ) { eventInfo = this.__in(eventInfo); if ( !eventInfo ) { return; } } switch( eventInfo.type ) { case paraemu.SYSTEM_EVENT.CUSTOM_EVENT: { let {event, eventData, sender, target} = eventInfo; eventData = Array.isArray(eventData) ? eventData : []; JOB_INST.__emit(event, {type:event, sender, target}, ...eventData); break; } case paraemu.SYSTEM_EVENT.DELIVERY_EVENT: if ( !broadcast ) { let {isAck, deliveryId, eventData, event, sender, target} = eventInfo; eventData = Array.isArray(eventData) ? eventData : []; if ( !isAck ) { const respondWith = (()=>{ let invoked = false; return (response=null)=>{ if ( invoked ) return; invoked = true; JOB_INST.__emit( paraemu.SYSTEM_HOOK.PARAEMU_EVENT, { type: paraemu.SYSTEM_EVENT.DELIVERY_EVENT, sender: JOB_ID, target: sender, isAck:1, deliveryId, event, eventData:[response] }); }; })(); JOB_INST.__emit( event, {type:event, sender, target, respondWith}, ...eventData); PASSIVE_DELIVERY_POOL[deliveryId]={ timeout:setTimeout(()=>{ delete ACTIVE_DELIVERY_POOL[deliveryId]; respondWith(); }, DELIVERY_RESPONSE_TIMEOUT) }; } else { let deliveryInfo; if ( deliveryInfo = ACTIVE_DELIVERY_POOL[deliveryId] ) { let { resolve, timeout } = deliveryInfo; clearTimeout(timeout); delete ACTIVE_DELIVERY_POOL[deliveryId]; resolve(eventData[0]); } } } break; default: break; } } }, true); JOB_INST.send = (target, event, ...args)=>{ JOB_INST.__emit( paraemu.SYSTEM_HOOK.PARAEMU_EVENT, { type: paraemu.SYSTEM_EVENT.CUSTOM_EVENT, sender:JOB_ID, target:target, event, eventData:args }); }; JOB_INST.emit = (event, ...args)=>{ JOB_INST.send( null, event, ...args ); }; JOB_INST.local = (event, ...args)=>{ JOB_INST.send( JOB_INST.groupId, event, ...args ); }; JOB_INST.deliver = (target, event, ...eventData)=>{ const deliveryId = GenObjectId().toString('base64url'); JOB_INST.__emit( paraemu.SYSTEM_HOOK.PARAEMU_EVENT, { type: paraemu.SYSTEM_EVENT.DELIVERY_EVENT, sender: JOB_ID, target: target, isAck:0, deliveryId, event, eventData }); return new Promise((resolve, reject)=>{ ACTIVE_DELIVERY_POOL[deliveryId]={ timeout:setTimeout(()=>{ delete ACTIVE_DELIVERY_POOL[deliveryId]; reject(); }, DELIVERY_TIMEOUT), resolve, reject }; }); }; // endregion return JOB_INST; }; })();