Skip to content

Commit

Permalink
Replace FunctionCall getResults by getLastResult.
Browse files Browse the repository at this point in the history
Fixes #9 where an infinite number of backoffs would exhaust the memory
as the intermediary results are accumulated.
  • Loading branch information
MathieuTurcotte committed Jun 20, 2014
1 parent fa0e59b commit 248cf47
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 21 deletions.
23 changes: 11 additions & 12 deletions README.md
Expand Up @@ -90,8 +90,6 @@ Typical usage looks like the following.

``` js
var call = backoff.call(get, 'https://duplika.ca/', function(err, res) {
console.log('Retries: ' + call.getResults().length);

if (err) {
console.log('Error: ' + err.message);
} else {
Expand Down Expand Up @@ -292,19 +290,20 @@ there is no limit on the number of backoffs that can be performed.
This method should be called before `call.start()` otherwise an exception will
be thrown..

#### call.getResults()
#### call.getLastResult()

Retrieves all intermediary results returned by the wrapped function. This
Retrieves the last intermediary result returned by the wrapped function. This
method can be called at any point in time during the call life cycle, i.e.
before, during and after the wrapped function invocation.

Returns an array of arrays containing the results returned by the wrapped
function for each call. For example, to get the error code returned by the
second call, one would do the following.
Returns an array containing the results returned by the last wrapped function
call. For example, to get the error code returned by the last call, one would
do the following.

``` js
var results = call.getResults();
var error = results[1][0];
var results = call.getLastResult();
// The error code is the first parameter of the callback.
var error = results[0];
```

#### call.start()
Expand All @@ -317,9 +316,9 @@ once otherwise an exception will be thrown.

Aborts the call.

Past results can be retrieved using `call.getResults()`. This method can be
called at any point in time during the call life cycle, i.e. before, during
and after the wrapped function invocation.
The last result can be retrieved using `call.getLastResult()`. This method
can be called at any point in time during the call life cycle, i.e. before,
during and after the wrapped function invocation.

#### Event: 'call'

Expand Down
2 changes: 1 addition & 1 deletion examples/function_call.js
Expand Up @@ -27,7 +27,7 @@ function get(options, callback) {

var call = backoff.call(get, URL, function(err, res) {
// Notice how the call is captured inside the closure.
console.log('Retries: ' + call.getResults().length);
console.log('Last result: ' + util.inspect(call.getLastResult()));

if (err) {
console.log('Error: ' + err.message);
Expand Down
11 changes: 5 additions & 6 deletions lib/function_call.js
Expand Up @@ -19,7 +19,7 @@ function FunctionCall(fn, args, callback) {
this.function_ = fn;
this.arguments_ = args;
this.callback_ = callback;
this.results_ = [];
this.lastResult_ = [];

this.backoff_ = null;
this.strategy_ = null;
Expand Down Expand Up @@ -72,8 +72,8 @@ FunctionCall.prototype.setStrategy = function(strategy) {

// Returns all intermediary results returned by the wrapped function since
// the initial call.
FunctionCall.prototype.getResults = function() {
return this.results_.concat();
FunctionCall.prototype.getLastResult = function() {
return this.lastResult_.concat();
};

// Sets the backoff limit.
Expand Down Expand Up @@ -129,8 +129,7 @@ FunctionCall.prototype.doCall_ = function() {
// Calls the wrapped function's callback with the last result returned by the
// wrapped function.
FunctionCall.prototype.doCallback_ = function() {
var args = this.results_[this.results_.length - 1];
this.callback_.apply(null, args);
this.callback_.apply(null, this.lastResult_);
};

// Handles wrapped function's completion. This method acts as a replacement
Expand All @@ -141,7 +140,7 @@ FunctionCall.prototype.handleFunctionCallback_ = function() {
}

var args = Array.prototype.slice.call(arguments);
this.results_.push(args); // Save callback arguments.
this.lastResult_ = args; // Save last callback arguments.
events.EventEmitter.prototype.emit.apply(this, ['callback'].concat(args));

if (args[0]) {
Expand Down
5 changes: 3 additions & 2 deletions tests/function_call.js
Expand Up @@ -241,20 +241,21 @@ exports["FunctionCall"] = {
test.done();
},

"getResults should return intermediary results": function(test) {
"getLastResult should return the last intermediary result": function(test) {
var call = new FunctionCall(this.wrappedFn, [], this.callback);
this.wrappedFn.yields(1);
call.start(this.backoffFactory);

for (var i = 2; i < 5; i++) {
this.wrappedFn.yields(i);
this.backoff.emit('ready');
test.deepEqual([i], call.getLastResult());
}

this.wrappedFn.yields(null);
this.backoff.emit('ready');
test.deepEqual([null], call.getLastResult());

test.deepEqual([[1], [2], [3], [4], [null]], call.getResults());
test.done();
},

Expand Down

0 comments on commit 248cf47

Please sign in to comment.