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.

Este script não deve ser instalado diretamente. Este script é uma biblioteca de outros scripts para incluir com o diretório meta // @require https://update.greasyfork.org/scripts/559799/1759938/Real-Time-Rate-Limiting-Queue.js

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

Autor
JasonMel
Versão
1.0.10
Criado
22/12/2025
Atualizado
27/12/2025
Tamanho
33,2 KB
Licença
MIT (https://mit-license.org/)

This library uses Mike Diarmid's Denque https://github.com/Salakar — copyright © 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:

const Rtrlq = getRtrlqClass();
const requests = 15;
const interval = Rtrlq.minutes(1);
const myQueue = new Rtrlq(requests, interval); // 15 allowed req/min

Additionally, any script using this library must include the following metadata:

(You must manually obtain the @require URLs of the latest dependency versions on their respective pages, since script managers apparently only update scripts, not @requires.)

This is necessary because this library @requires a subordinate library, and

  1. Scripts must @require all dependencies recursively (i.e., its dependencies, its dependencies' dependencies, its dependencies' dependencies' dependencies, etc).
  2. Scripts must include all @grants needed by each dependency, recursively.

So don't make the mistake that I made, and think that putting what each library needs in its own metadata is enough. It's not!


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, tested example of how an instance of the queue class, named myRtrlQueue, might be created and used in practice.

const Rtrlq = getRtrlqClass();
const myRtrlQueue = new Rtrlq(3, Rtrlq.seconds(5)); // max of 3 requests every 5 seconds
const URL = "https://www.some.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}`);
        }
        return response.text();
    })
    .then(bodyText => console.log(`Queued request ${item.id} succeeded: ${bodyText}`))
    .catch(err =>   console.error(`Queued request ${item.id} failed: ${err}`)));