1 | # patiently
|
2 | Promise based API rate limit handler. Make your API client patient. A legal way to wait for API rate limit resets.
|
3 |
|
4 | [![npm version](https://img.shields.io/npm/v/patiently.svg?style=flat-square)](https://www.npmjs.com/package/patiently)
|
5 | [![install size](https://packagephobia.now.sh/badge?p=patiently)](https://packagephobia.now.sh/result?p=patiently)
|
6 | [![Downloads](https://badgen.net/npm/dt/patiently)](https://www.npmjs.com/package/patiently)
|
7 | ![license](https://badgen.net/npm/license/patiently)
|
8 |
|
9 | ## Purpose
|
10 |
|
11 | Sometimes there is no other way to be patient and to wait for the API rate limit to reset. Just think of a personalized API that allows you to perform actions in a specific user context. You want to do like 10.000 reqs as fast as possible. What if there are rate limits like 50 reqs per minute and 750 reqs per hour? And what if those limits are not bound to an IP or a host but to your user? In this case there is no other way but to wait for a limit reset. Of course, you can also politely ask the API owner to increase the limits. But even then you need **patiently**. :)
|
12 |
|
13 | ## Features
|
14 |
|
15 | - **patiently** will handle API rate limits for you and make your API client wait for a limit reset automatically
|
16 | - set minutely or hourly rate limits manually
|
17 |
|
18 | ## Planned Features
|
19 |
|
20 | - [x] Add secondly limit feature (e.g. 2 reqs per second).
|
21 | - [] If required I can add a "maxConcurrent" feature like in [bottleneck](https://www.npmjs.com/package/bottleneck)
|
22 | - [] I'm also trying to figure out how to deal with rate limit headers like ```x-ratelimit-remaining``` or ```retry-after```. At first sight this is not so easy, because the first headers only arrive after the first API call. And until then, any number of API calls could have been fired.
|
23 |
|
24 | ## Installing
|
25 |
|
26 | Using npm:
|
27 |
|
28 | ```bash
|
29 | $ npm install patiently
|
30 | ```
|
31 |
|
32 | ## How to use
|
33 |
|
34 | ### Use by setting limits manually
|
35 |
|
36 | Perhaps you already know about the limits (maybe from the API docs).
|
37 |
|
38 | ```javascript
|
39 | import patiently from "patiently";
|
40 |
|
41 | let options = {
|
42 | startWaitingCallback: function(info){console.log(info)}, // default is function(){}, calls a function if waiting necessary
|
43 | endWaitingCallback: function(info){console.log(info)}, // default is function(){}, calls a function after waiting
|
44 | waitingTickCallback: function(info){console.log(info)}, // default is function(){}, calls a function every tick
|
45 | msBetweenTwoCalls: 1000, // default is 0 milliseconds (no waiting time between two calls)
|
46 | minutelyLimit: 50, // default is Infinity (no minutely limit set)
|
47 | hourlyLimit: 750, // default is Infinity (no hourly limit set)
|
48 | test: false // default is false (if true, max waiting time is 5 secs)
|
49 | }
|
50 |
|
51 | var waiter = patiently.LimitWaiter(options);
|
52 |
|
53 | let myApiCallFunction = async () => {
|
54 | waiter.wait(function(){
|
55 | // your api call
|
56 | })
|
57 | }
|
58 |
|
59 | // you can call myApiCallFunction as often you want
|
60 | // patiently can handle asynchronous api calls :)
|
61 | myApiCallFunction();
|
62 | myApiCallFunction();
|
63 | myApiCallFunction();
|
64 | myApiCallFunction();
|
65 | // ...
|
66 | ```
|
67 |
|
68 | ## How does it work?
|
69 |
|
70 | - Each function you give to the waiter as a parameter is queued in an array
|
71 | - ``` F -> E D C B A```
|
72 |
|
73 | - The longest waiting function is first
|
74 | - ``` F E D C B -> A```
|
75 | - Before the function is called, it is checked whether we have to wait first or not
|
76 | - ``` F E D C B -> A (wait?)```
|
77 | - If yes the queue processing is *paused* and when the waiting time elapsed, function A will be called
|
78 | - ``` F E D C B -> A (call)```
|
79 |
|
80 | ## License
|
81 |
|
82 | MIT
|
83 |
|
\ | No newline at end of file |