Real-Time-Rate-Limiting-Queue

If more requests are made within the specified interval than the specified number, it waits until the oldest one is older than the interval before making the next request in the queue.

Questo script non dovrebbe essere installato direttamente. È una libreria per altri script da includere con la chiave // @require https://update.greasyfork.org/scripts/559799/1719672/Real-Time-Rate-Limiting-Queue.js

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

Autore
JasonMel
Versione
1.0.0
Creato il
22/12/2025
Aggiornato il
23/12/2025
Dimensione
34,7 KB
Licenza
MIT https://mit-license.org/

This library uses Mike Diarmid's Denque https://github.com/Salakar — copyright (c) 2018 Invertase Limited https://github.com/invertase/denque


Sometimes, a script may need to make many requests to a site. If the script makes enough requests in a short enough time, the site may consequently become annoyed at their server getting hammered. Some sites actually require scripts to limit requests to a published frequency or face consequences of some sort. This class allows you to automatically limit the frequency of requests that your script makes.

What makes this class special is that the rate is limited in real time, which all but guarantees that any given request will be made the moment the timeline of your past requests permits it, without, for example, waiting for a multiple of the interval to pass, or recomputing an equivalent rate based on a different interval.

This class requires some familiarity with the use of javascript Promises. A good primer is https://javascript.info/async.


To use, access

globalThis[meta]

where meta is a string key composed of the @required script's metadata @namespace, @name, and the major version number of @version, joined with colons. I.e.,

globalThis["github.com/JasonAMelancon:Real-Time-Rate-Limiting-Queue:1"]

In a script that @requires this script, the above expression will evaluate to the Real-time Rate-limiting Queue class, which can be assigned to a variable, which is then usable as the class identifier.

(Only the major version is used because updating the script changes the version number, which would break this mechanism, but a new major version would typically break including scripts anyway.)


All documentation is available as JSDoc comments. Where this excerpt of the JSDoc differs from that found in the code, prefer the latter.

constructor(reqPerInterval, interval, concurrent, array, dequeOptions)

Instantiates the queue.

reqPerInterval Requests per interval. The numerator of the queue rate parameter. Will be set to the default of 1 if not a valid positive number.

interval The denominator of the queue rate parameter in milliseconds. Will be set to the default of 0 if not a valid non-negative number. 0 disables rate limit.

concurrent Pass in false if each item should wait for the last to finish before executing. Only inherently asynchronous operations may be concurrent.

array Can be supplied if the desired item queue exists as an array already. Note that queue execution only begins on enqueueing an object.

dequeOptions Passed on to internal deque class, which currently ignores it. See Denque module (https://github.com/invertase/denque).

enqueue(item)

Enqueue the item object itself (not a copy).

item To be useful, this must have a function in its "executor" or "callback" property. This is the request whose rate of calling will be controlled. If supplied, the executor property must contain a function of the kind that Promise() takes. If there is a callback and no executor, the callback should return either a truthy value (which may be a result), or a falsy value indicating failure. In either case, the item will be given a "timestamp" property containing the javascript datetime of the request execution, a boolean "success" property, and a "promise" property containing a Promise, automatically constructed from the executor if supplied, holding the result of the request. Rejected Promises and failed callbacks will not count toward the rate limit. These should result from, for example, fetching an invalid URL or having no network, but not from a 404 Not Found, which would typically still count since it requires server time.

Returns a Promise that resolves to the supplied item once its promise property is settled. Do not confuse these two Promises! This one resolves to the enqueued item when its request is settled, while the Promise on the item itself contains the result of the request. This is in order to make the other information on the item available when the request result is accessed.

Here is a brief example of how an instance of the queue class, named myRtrlQueue, would be created and used in practice.

const Rtrlq = globalThis["github.com/JasonAMelancon:Real-Time-Rate-Limiting-Queue:1"];
const myRtrlQueue = new Rtrlq(3, Rtrlq.seconds(5)); // max of 3 requests every 5 seconds
const URL = "https://www.site.net/api/some/text/";
// ...
const queueItem = myRtrlQueue.enqueue({
                     executor: (resolve, reject) => fetch(URL).then(resolve, reject),
                     id: 69105
                  });
// ...
// now examine request result, along with any associated data you put on the queue item
queueItem.then(item => item.promise
    .then(response => {
        if (!response.ok) {
            throw new Error(`${response.status} - ${response.statusText}`);
        }
        console.log(`Queued request ${item.id} succeeded: ${response.body}`);
    })
    .catch(err => console.error(`Queued request ${item.id} failed: ${err}`)));