blob: 17bee28722c93377ada44ada66b328e77d94a5b5 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Provides a watchdog around a collection of callback functions.
*/
'use strict';
/**
* Creates a watchdog around a collection of callback functions,
* ensuring at least one of them is called before the timeout expires.
* If a timeout function is provided, calls the timeout function upon timeout
* expiration if none of the callback functions has been called.
* @param {number} timeoutValueSeconds Timeout value, in seconds.
* @param {function()=} opt_timeoutCb Callback function to call on timeout.
* @constructor
* @implements {Closeable}
*/
function WatchdogRequestHandler(timeoutValueSeconds, opt_timeoutCb) {
/** @private {number} */
this.timeoutValueSeconds_ = timeoutValueSeconds;
/** @private {function()|undefined} */
this.timeoutCb_ = opt_timeoutCb;
/** @private {boolean} */
this.calledBack_ = false;
/** @private {Countdown} */
this.timer_ = FACTORY_REGISTRY.getCountdownFactory().createTimer(
this.timeoutValueSeconds_ * 1000, this.timeout_.bind(this));
/** @private {Closeable|undefined} */
this.closeable_ = undefined;
/** @private {boolean} */
this.closed_ = false;
}
/**
* Wraps a callback function, such that the fact that the callback function
* was or was not called gets tracked by this watchdog object.
* @param {function(...?)} cb The callback function to wrap.
* @return {function(...?)} A wrapped callback function.
*/
WatchdogRequestHandler.prototype.wrapCallback = function(cb) {
return this.wrappedCallback_.bind(this, cb);
};
/** Closes this watchdog. */
WatchdogRequestHandler.prototype.close = function() {
this.closed_ = true;
this.timer_.clearTimeout();
if (this.closeable_) {
this.closeable_.close();
this.closeable_ = undefined;
}
};
/**
* Sets this watchdog's closeable.
* @param {!Closeable} closeable The closeable.
*/
WatchdogRequestHandler.prototype.setCloseable = function(closeable) {
this.closeable_ = closeable;
};
/**
* Called back when the watchdog expires.
* @private
*/
WatchdogRequestHandler.prototype.timeout_ = function() {
if (!this.calledBack_ && !this.closed_) {
var logMsg = 'Not called back within ' + this.timeoutValueSeconds_ +
' second timeout';
if (this.timeoutCb_) {
logMsg += ', calling default callback';
console.warn(UTIL_fmt(logMsg));
this.timeoutCb_();
} else {
console.warn(UTIL_fmt(logMsg));
}
}
};
/**
* Wrapped callback function.
* @param {function(...?)} cb The callback function to call.
* @param {...?} var_args The callback function's arguments.
* @private
*/
WatchdogRequestHandler.prototype.wrappedCallback_ = function(cb, var_args) {
if (!this.closed_) {
this.calledBack_ = true;
this.timer_.clearTimeout();
var originalArgs = Array.prototype.slice.call(arguments, 1);
cb.apply(null, originalArgs);
}
};