Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * A timer that will execute a callback with decreasing frequency. Useful for
18
 * doing polling on the server without overwhelming it with requests.
19
 *
20
 * @module     core/backoff_timer
21
 * @copyright  2016 Ryan Wyllie <ryan@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
define(function() {
25
 
26
    /**
27
     * Constructor for the back off timer.
28
     *
29
     * @class
30
     * @param {function} callback The function to execute after each tick
31
     * @param {function} backoffFunction The function to determine what the next timeout value should be
32
     */
33
    var BackoffTimer = function(callback, backoffFunction) {
34
        this.callback = callback;
35
        this.backOffFunction = backoffFunction;
36
    };
37
 
38
    /**
39
     * @property {function} callback The function to execute after each tick
40
     */
41
    BackoffTimer.prototype.callback = null;
42
 
43
    /**
44
     * @property {function} backoffFunction The function to determine what the next timeout value should be
45
     */
46
    BackoffTimer.prototype.backOffFunction = null;
47
 
48
    /**
49
     * @property {int} time The timeout value to use
50
     */
51
    BackoffTimer.prototype.time = null;
52
 
53
    /**
54
     * @property {numeric} timeout The timeout identifier
55
     */
56
    BackoffTimer.prototype.timeout = null;
57
 
58
    /**
59
     * Generate the next timeout in the back off time sequence
60
     * for the timer.
61
     *
62
     * The back off function is called to calculate the next value.
63
     * It is given the current value and an array of all previous values.
64
     *
65
     * @return {int} The new timeout value (in milliseconds)
66
     */
67
    BackoffTimer.prototype.generateNextTime = function() {
68
        var newTime = this.backOffFunction(this.time);
69
        this.time = newTime;
70
 
71
        return newTime;
72
    };
73
 
74
    /**
75
     * Stop the current timer and clear the previous time values
76
     *
77
     * @return {object} this
78
     */
79
    BackoffTimer.prototype.reset = function() {
80
        this.time = null;
81
        this.stop();
82
 
83
        return this;
84
    };
85
 
86
    /**
87
     * Clear the current timeout, if one is set.
88
     *
89
     * @return {object} this
90
     */
91
    BackoffTimer.prototype.stop = function() {
92
        if (this.timeout) {
93
            window.clearTimeout(this.timeout);
94
            this.timeout = null;
95
        }
96
 
97
        return this;
98
    };
99
 
100
    /**
101
     * Start the current timer by generating the new timeout value and
102
     * starting the ticks.
103
     *
104
     * This function recurses after each tick with a new timeout value
105
     * generated each time.
106
     *
107
     * The callback function is called after each tick.
108
     *
109
     * @return {object} this
110
     */
111
    BackoffTimer.prototype.start = function() {
112
        // If we haven't already started.
113
        if (!this.timeout) {
114
            var time = this.generateNextTime();
115
            this.timeout = window.setTimeout(function() {
116
                this.callback();
117
                // Clear the existing timer.
118
                this.stop();
119
                // Start the next timer.
120
                this.start();
121
            }.bind(this), time);
122
        }
123
 
124
        return this;
125
    };
126
 
127
    /**
128
     * Reset the timer and start it again from the initial timeout
129
     * values
130
     *
131
     * @return {object} this
132
     */
133
    BackoffTimer.prototype.restart = function() {
134
        return this.reset().start();
135
    };
136
 
137
    /**
138
     * Returns an incremental function for the timer.
139
     *
140
     * @param {int} minamount The minimum amount of time we wait before checking
141
     * @param {int} incrementamount The amount to increment the timer by
142
     * @param {int} maxamount The max amount to ever increment to
143
     * @param {int} timeoutamount The timeout to use once we reach the max amount
144
     * @return {function}
145
     */
146
     BackoffTimer.getIncrementalCallback = function(minamount, incrementamount, maxamount, timeoutamount) {
147
 
148
        /**
149
         * An incremental function for the timer.
150
         *
151
         * @param {(int|null)} time The current timeout value or null if none set
152
         * @return {int} The new timeout value
153
         */
154
        return function(time) {
155
            if (!time) {
156
                return minamount;
157
            }
158
 
159
            // Don't go over the max amount.
160
            if (time + incrementamount > maxamount) {
161
                return timeoutamount;
162
            }
163
 
164
            return time + incrementamount;
165
        };
166
    };
167
 
168
    return BackoffTimer;
169
});