| // 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); |
| } |
| }; |