1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview Provides a countdown-based timer implementation.
11 * Constructs a new timer. The timer has a very limited resolution, and does
12 * not attempt to be millisecond accurate. Its intended use is as a
13 * low-precision timer that pauses while debugging.
14 * @param {number=} timeoutMillis how long, in milliseconds, the countdown
16 * @param {Function=} cb called back when the countdown expires.
18 * @implements {Countdown}
20 function CountdownTimer(timeoutMillis
, cb
) {
21 this.remainingMillis
= 0;
22 this.setTimeout(timeoutMillis
|| 0, cb
);
26 CountdownTimer
.TIMER_INTERVAL_MILLIS
= 200;
29 * Sets a new timeout for this timer. Only possible if the timer is not
31 * @param {number} timeoutMillis how long, in milliseconds, the countdown lasts.
32 * @param {Function=} cb called back when the countdown expires.
33 * @return {boolean} whether the timeout could be set.
35 CountdownTimer
.prototype.setTimeout = function(timeoutMillis
, cb
) {
38 if (!timeoutMillis
|| timeoutMillis
< 0)
40 this.remainingMillis
= timeoutMillis
;
42 if (this.remainingMillis
> CountdownTimer
.TIMER_INTERVAL_MILLIS
) {
44 window
.setInterval(this.timerTick
.bind(this),
45 CountdownTimer
.TIMER_INTERVAL_MILLIS
);
47 // Set a one-shot timer for the last interval.
49 window
.setTimeout(this.timerTick
.bind(this), this.remainingMillis
);
54 /** Clears this timer's timeout. Timers that are cleared become expired. */
55 CountdownTimer
.prototype.clearTimeout = function() {
57 window
.clearTimeout(this.timeoutId
);
58 this.timeoutId
= undefined;
60 this.remainingMillis
= 0;
64 * @return {number} how many milliseconds are remaining until the timer expires.
66 CountdownTimer
.prototype.millisecondsUntilExpired = function() {
67 return this.remainingMillis
> 0 ? this.remainingMillis
: 0;
70 /** @return {boolean} whether the timer has expired. */
71 CountdownTimer
.prototype.expired = function() {
72 return this.remainingMillis
<= 0;
76 * Constructs a new clone of this timer, while overriding its callback.
77 * @param {Function=} cb callback for new timer.
78 * @return {!Countdown} new clone.
80 CountdownTimer
.prototype.clone = function(cb
) {
81 return new CountdownTimer(this.remainingMillis
, cb
);
84 /** Timer callback. */
85 CountdownTimer
.prototype.timerTick = function() {
86 this.remainingMillis
-= CountdownTimer
.TIMER_INTERVAL_MILLIS
;
88 window
.clearTimeout(this.timeoutId
);
89 this.timeoutId
= undefined;
97 * A factory for creating CountdownTimers.
99 * @implements {CountdownFactory}
101 function CountdownTimerFactory() {
105 * Creates a new timer.
106 * @param {number} timeoutMillis How long, in milliseconds, the countdown lasts.
107 * @param {function()=} opt_cb Called back when the countdown expires.
108 * @return {!Countdown} The timer.
110 CountdownTimerFactory
.prototype.createTimer
=
111 function(timeoutMillis
, opt_cb
) {
112 return new CountdownTimer(timeoutMillis
, opt_cb
);
116 * Minimum timeout attenuation, below which a response couldn't be reasonably
117 * guaranteed, in seconds.
120 var MINIMUM_TIMEOUT_ATTENUATION_SECONDS
= 0.5;
123 * @param {number} timeoutSeconds Timeout value in seconds.
124 * @return {number} The timeout value, attenuated to ensure a response can be
125 * given before the timeout's expiration.
128 function attenuateTimeoutInSeconds_(timeoutSeconds
) {
129 if (timeoutSeconds
< MINIMUM_TIMEOUT_ATTENUATION_SECONDS
)
131 return timeoutSeconds
- MINIMUM_TIMEOUT_ATTENUATION_SECONDS
;
135 * Default request timeout when none is present in the request, in seconds.
138 var DEFAULT_REQUEST_TIMEOUT_SECONDS
= 30;
141 * Creates a new countdown from the given request using the given timer factory,
142 * attenuated to ensure a response is given prior to the countdown's expiration.
143 * @param {CountdownFactory} timerFactory The factory to use.
144 * @param {Object} request The request containing the timeout.
145 * @param {number=} opt_defaultTimeoutSeconds
146 * @return {!Countdown} A countdown timer.
148 function createTimerForRequest(timerFactory
, request
,
149 opt_defaultTimeoutSeconds
) {
150 var timeoutValueSeconds
;
151 if (request
.hasOwnProperty('timeoutSeconds')) {
152 timeoutValueSeconds
= request
['timeoutSeconds'];
153 } else if (request
.hasOwnProperty('timeout')) {
154 timeoutValueSeconds
= request
['timeout'];
155 } else if (opt_defaultTimeoutSeconds
!== undefined) {
156 timeoutValueSeconds
= opt_defaultTimeoutSeconds
;
158 timeoutValueSeconds
= DEFAULT_REQUEST_TIMEOUT_SECONDS
;
160 timeoutValueSeconds
= attenuateTimeoutInSeconds_(timeoutValueSeconds
);
161 return timerFactory
.createTimer(timeoutValueSeconds
* 1000);