Skip to content

Commit

Permalink
Merge pull request #109 from trayio/CN-40/promise-timeout
Browse files Browse the repository at this point in the history
CN 40/promise timeout
  • Loading branch information
Johnbastian authored Jan 9, 2019
2 parents 70f5dce + cb88569 commit 3875feb
Show file tree
Hide file tree
Showing 4 changed files with 405 additions and 41 deletions.
111 changes: 78 additions & 33 deletions lib/bindConnectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,38 @@ module.exports = function (config, options) {
// Dont wait for event loop to be empty when callback is called
context.callbackWaitsForEmptyEventLoop = false;


/*
If context.getRemainingTimeInMillis is available, set it's value
minus 5 seconds, and make sure it is positive; else set the
timeout to 0 (such that it is falsy)
*/
var timeRemaining = (
_.isPlainObject(context) && _.isFunction(context.getRemainingTimeInMillis) ?
context.getRemainingTimeInMillis() :
0
);
var promiseTimeout = timeRemaining - 5000;
promiseTimeout = ( promiseTimeout < 1 ? 0 : promiseTimeout );


// The array of events should all be executed in parallel
var promises = _.map(events, function (event) {
return when.promise(function (resolve, reject) {

var messagePromise = when.promise(function (resolve, reject) {

// Handle error invalid payload
if (!event.header || !event.header.message) {
return resolve(
formatError(
{
headers: {},
body: {
code: 'invalid_input',
message: 'Invalid message received.'
}
},
event
)
);
return resolve(formatError(
{
headers: {},
body: {
code: 'invalid_input',
message: 'Invalid message received.'
}
},
event
));
}


Expand All @@ -63,18 +77,16 @@ module.exports = function (config, options) {

// Handle message not existing
if (!_.isFunction(hooks[event.header.message])) {
return resolve(
formatError(
{
headers: {},
body: {
code: 'not_implemented',
message: 'Could not find a valid message handler for ' + event.header.message
}
},
event
)
);
return resolve(formatError(
{
headers: {},
body: {
code: 'not_implemented',
message: 'Could not find a valid message handler for ' + event.header.message
}
},
event
));
}

// Got this far? All good, let's run
Expand All @@ -87,19 +99,52 @@ module.exports = function (config, options) {

.done(
function (response) {
resolve(
( _.isError(response.body) ?
formatError(response, event) :
formatMessage(event, response, response.version)
)
);
}, function (response) {
resolve((
_.isError(response.body) ?
formatError(response, event) :
formatMessage(event, response, response.version)
));
},
function (response) {
resolve(formatError(response, event));
}
);


});

//If a non-0 value is present, add a timeout condition to the promise
if (promiseTimeout) {

return messagePromise

.timeout(promiseTimeout)

//Perform this catch only if it is due to timeout
.catch(when.TimeoutError, function () {
// eslint-disable-next-line no-console
console.warn('The promise has not been closed within the time limit.', event.header.message);
//NOTE: this reject will force this lambda function to error (not the operation only)
return when.reject(formatError(
{
headers: {},
body: {
code: '#fatal_error',
message: 'The operation timed out.',
payload: {
reason: 'The operation has timed out due to the promise not closing (resolving/rejecting) within the time limit.',
operation: event.header.message
}
}
},
event
));
});

}


return messagePromise;

});

// Wait for all of the above to finish, then resolve
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@trayio/falafel",
"version": "1.14.1",
"description": "",
"version": "1.15.0",
"description": "A framework for developing and running connectors.",
"main": "lib/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
Loading

0 comments on commit 3875feb

Please sign in to comment.