var _ = require('lodash'),
createItemContext = require('./create-item-context'),
// total number of replays allowed
MAX_REPLAY_COUNT = 3,
ReplayController;
/**
* Handles replay logic with replayState from context.
* Makes sure request replays do not go into an infinite loop.
*
* @param {ReplayState} replayState
* @param {Run} run
*
* @constructor
*/
ReplayController = function ReplayController (replayState, run) {
// store state
this.count = replayState ? replayState.count : 0;
this.run = run;
};
_.assign(ReplayController.prototype, /** @lends ReplayController.prototype */{
/**
* Sends a request in the item. This takes care of limiting the total number of replays for a request.
*
* @param {Object} context
* @param {Request} item
* @param {Object} desiredPayload a partial payload to use for the replay request
* @param {Function} success this callback is invoked when replay controller sent the request
* @param {Function} failure this callback is invoked when replay controller decided not to send the request
*/
requestReplay: function (context, item, desiredPayload, success, failure) {
// max retries exceeded
if (this.count >= MAX_REPLAY_COUNT) {
return failure(new Error('runtime: maximum intermediate request limit exceeded'));
}
// update replay count state
this.count++;
// update replay state to context
context.replayState = this.getReplayState();
// construct payload for request
var payload = _.defaults({
item: item,
// abortOnError makes sure request command bubbles errors
// so we can pass it on to the callback
abortOnError: true
}, desiredPayload);
// create item context from the new item
payload.context = createItemContext(payload, context);
this.run.immediate('httprequest', payload)
.done(function (response) {
success(null, response);
})
.catch(success);
},
/**
* Returns a serialized version of current ReplayController
*
* @returns {ReplayState}
*/
getReplayState: function () {
/**
* Defines the current replay state of a request.
*
* By replay state, we mean the number of requests sent
* as part of one Collection requests. It can be intermediate requests,
* or replays of the same collection requests.
*
* @typedef {Object} ReplayState
*
* @property {Number} count total number of requests, including Collection requests and replays
*/
return {
count: this.count
};
}
});
module.exports = ReplayController;