Skip to content

Commit

Permalink
Implement more callback argument functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Jashepp committed Jul 12, 2017
1 parent 515748a commit be38f0b
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 14 deletions.
5 changes: 5 additions & 0 deletions examples/tests_module.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,8 @@ exports.multipleCallbacks = (...cb)=>{
}
return 'bar';
};

exports.multiCallsCallback = (cb,times)=>{
for(var i=0; i<times; i++) cb(i);
return true;
};
66 changes: 60 additions & 6 deletions lib/proxy-constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,31 +244,85 @@ const proxyConstructor = exports.proxyConstructor = class proxyConstructor {
if (value === false) delete actionConfig[key];
});
var actionData = { returnEventName, interfaceID, actionID, property, newOperator, args, argsConfig:{}, actionConfig };
this.proxyPromiseArguments(proxyPromise,actionData);
this.handlePromiseArguments(proxyPromise,actionData);
this.proxyCom.transport.once(returnEventName, (...args)=>this.proxyPromiseResult(proxyPromise, actionData, ...args));
this.proxyCom.transport.send("proxyAction", actionData);
}

proxyPromiseArguments(proxyPromise,actionData){
handlePromiseArguments(proxyPromise,actionData){
var { proxyOptions } = proxyPromise;
var { interfaceID, actionID, args, argsConfig } = actionData;
var callbackLimit = _.has(proxyOptions,'callbackLimit') ? proxyOptions.callbackLimit*1 : 1;
var callbackTimeout = _.has(proxyOptions,'callbackTimeout') ? proxyOptions.callbackTimeout*1 : 0;
var callbackStopPromise = _.has(proxyOptions,'callbackStopPromise') && _.isPromise(proxyOptions.callbackStopPromise) && proxyOptions.callbackStopPromise;
var callbackOnRemove = _.has(proxyOptions,'callbackOnRemove') && _.isFunction(proxyOptions.callbackOnRemove) && (()=>{
try{ proxyOptions.callbackOnRemove(); }catch(err){};
});
args.forEach((arg,i)=>{
if(_.isFunction(arg)){
var argumentActionID = proxyPromise.argsActionID++;
var returnEventName = 'proxyActionArgument:' + interfaceID + ':' + actionID + ':' + argumentActionID;
args[i] = null;
argsConfig[i] = { type:'function', returnEventName };
this.proxyCom.transport.once(returnEventName, (funcArgs)=>arg(...funcArgs));
var onListener = null, onceListener = null;
var callArg = (funcArgs)=>{
try{ arg(...funcArgs); }catch(err){}
};
var cancelListener = ()=>{
cancelListener = ()=>{};
proxyPromise.removeArgumentCallbackListeners();
};
this.proxyCom.transport.once(returnEventName+':cancel',cancelListener);
var removeCancelListener = ()=>{
removeCancelListener = ()=>{};
this.proxyCom.transport.removeListener(returnEventName+':cancel',cancelListener);
};
if(callbackLimit>1) {
var callCount = 0;
onListener = (...funcArgs)=>{
if(callCount>callbackLimit) return;
callCount++;
callArg(...funcArgs);
if(callCount>=callbackLimit) proxyPromise.removeArgumentCallbackListeners();
};
}
else if(callbackLimit===0) onListener = callArg;
else onceListener = (...funcArgs)=>{
callArg(...funcArgs);
removeCancelListener();
if(callbackOnRemove) callbackOnRemove();
};
if(onListener!==null) this.proxyCom.transport.on(returnEventName,onListener);
else if(onceListener!==null) this.proxyCom.transport.once(returnEventName,onceListener);
var tmr = null;
proxyPromise.removeArgumentCallbackListeners = ()=>{
proxyPromise.removeArgumentCallbackListeners = ()=>{};
if(tmr){ clearTimeout(tmr); tmr = null; }
if(onListener!==null) this.proxyCom.transport.removeListener(returnEventName,onListener);
else if(onceListener!==null) this.proxyCom.transport.removeListener(returnEventName,onceListener);
if(callbackOnRemove) callbackOnRemove();
removeCancelListener();
};
if(callbackTimeout>0){
tmr = setTimeout(()=>proxyPromise.removeArgumentCallbackListeners(),callbackTimeout);
}
if(callbackStopPromise){
callbackStopPromise.then(()=>proxyPromise.removeArgumentCallbackListeners());
}
}
});
}

proxyPromiseResult(promiseObj, actionData, resultObj) {
var {resolve: resolveOriginal, reject: rejectOriginal} = promiseObj;
proxyPromiseResult(proxyPromise, actionData, resultObj) {
var {resolve: resolveOriginal, reject: rejectOriginal} = proxyPromise;
var { error, type, result } = resultObj;
if (actionData.handledResult) return;
actionData.handledResult = true;
var resolve = (obj)=>this.proxyPromiseResult_parseObject(actionData, obj, resolveOriginal);
var reject = (obj)=>this.proxyPromiseResult_parseObject(actionData, obj, rejectOriginal);
var reject = (obj)=>{
if('removeArgumentCallbackListeners' in proxyPromise) proxyPromise.removeArgumentCallbackListeners();
return this.proxyPromiseResult_parseObject(actionData, obj, rejectOriginal);
};
if (error) {
var errorResult = this.proxyPromiseResult_error(error);
if (actionData.actionConfig && actionData.actionConfig.resolveError) return resolve({error: errorResult});
Expand Down
29 changes: 21 additions & 8 deletions lib/proxy-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ const dataHandler = exports.dataHandler = class dataHandler {
var { actionData, target, result, targetMethod } = handleData;
var { returnEventName, interfaceID, actionID, property, newOperator, args, argsConfig, actionConfig } = actionData;
var resultTarget = hasResult ? result : target[property];
// Handle arguments
this.handleActionArguments(handleData);
// Target Methods
switch (targetMethod) {
// Promisify Function
Expand All @@ -292,18 +294,11 @@ const dataHandler = exports.dataHandler = class dataHandler {
// Function
case targetMethods.function:
if (!hasResult){
// Handle arguments
_.each(argsConfig,(config,i)=>{
if(config.type==='function'){
args[i] = (...funcArgs)=>{
this.proxyCom.transport.send(config.returnEventName, funcArgs);
}
}
});
// Call function
let r;
if (newOperator) r = new target[property](...args);
else r = target[property](...args);
handleData.actionData.args = []; handleData.actionData.argsConfig = {};
handleData.result = r;
return this.handleActionTarget(handleData);
} else {
Expand Down Expand Up @@ -385,4 +380,22 @@ const dataHandler = exports.dataHandler = class dataHandler {
}
}

handleActionArguments(handleData){
var targetMethod = handleData.targetMethod;
var { args, argsConfig } = handleData.actionData;
_.each(argsConfig,(config,i)=>{
if(config.type==='function'){
if(targetMethod!==targetMethods.function){
this.proxyCom.transport.send(config.returnEventName+':cancel');
args[i] = ()=>{};
}
else {
args[i] = (...funcArgs)=>{
this.proxyCom.transport.send(config.returnEventName, funcArgs);
}
}
}
});
}

};
51 changes: 51 additions & 0 deletions tests/2-data-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,57 @@ describe("Require-Worker Data Types",()=>{
}).catch(done);
});

it("Multiple Callback Calls via .configure({ callbackLimit:x })",function(done){
this.timeout(500);
var done2 = _.after(10,done);
var checkCount = 0;
proxy.multiCallsCallback((i)=>{
checkCount++;
done2();
},8) // Anymore than 8 will simply be ignored on the client
.configure({ callbackLimit:8, callbackOnRemove:()=>{
if(checkCount<8) done("Callback Limit Not Reached? checkCount="+checkCount);
else done2();
} })
.then(({value})=>{
expect(value).to.equal(true);
done2();
}).catch(done);
});

it("Multiple Callback Calls hit Limit",function(done){
this.timeout(500);
var done2 = _.after(3,done);
var checkCount = 0;
proxy.multiCallsCallback((i)=>{
checkCount++;
if(checkCount>1) done("Callback Calls Over Limit? checkCount="+checkCount);
else done2();
},2)
.configure({ callbackLimit:1, callbackOnRemove:()=>{
done2();
} })
.then(({value})=>{
expect(value).to.equal(true);
done2();
}).catch(done);
});

it("Multiple Callback Calls no Limit",function(done){
this.timeout(500);
var done2 = _.after(2,done);
var checkCount = 0;
proxy.multiCallsCallback((i)=>{
checkCount++;
if(checkCount>=10) done2();
},10)
.configure({ callbackLimit:0 })
.then(({value})=>{
expect(value).to.equal(true);
done2();
}).catch(done);
});

});

});
Expand Down

0 comments on commit be38f0b

Please sign in to comment.