UNPKG

4.68 kBMarkdownView Raw
1# plugin-throttling.js
2
3> Octokit plugin for GitHub’s recommended request throttling
4
5[![@latest](https://img.shields.io/npm/v/@octokit/plugin-throttling.svg)](https://www.npmjs.com/package/@octokit/plugin-throttling)
6[![Build Status](https://github.com/octokit/plugin-throttling.js/workflows/Test/badge.svg)](https://github.com/octokit/plugin-throttling.js/actions?workflow=Test)
7
8Implements all [recommended best practices](https://docs.github.com/en/rest/guides/best-practices-for-integrators) to prevent hitting secondary rate limits.
9
10## Usage
11
12<table>
13<tbody valign=top align=left>
14<tr><th>
15Browsers
16</th><td width=100%>
17
18Load `@octokit/plugin-throttling` and [`@octokit/core`](https://github.com/octokit/core.js) (or core-compatible module) directly from [cdn.skypack.dev](https://cdn.skypack.dev)
19
20```html
21<script type="module">
22 import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
23 import { throttling } from "https://cdn.skypack.dev/@octokit/plugin-throttling";
24</script>
25```
26
27</td></tr>
28<tr><th>
29Node
30</th><td>
31
32Install with `npm install @octokit/core @octokit/plugin-throttling`. Optionally replace `@octokit/core` with a core-compatible module.
33
34**Note**: If you use it with `@octokit/rest` v16, install `@octokit/core` as a devDependency. This is only temporary and will no longer be necessary with `@octokit/rest` v17.
35
36```js
37const { Octokit } = require("@octokit/core");
38const { throttling } = require("@octokit/plugin-throttling");
39```
40
41</td></tr>
42</tbody>
43</table>
44
45The code below creates a "Hello, world!" issue on every repository in a given organization. Without the throttling plugin it would send many requests in parallel and would hit rate limits very quickly. But the `@octokit/plugin-throttling` slows down your requests according to the official guidelines, so you don't get blocked before your quota is exhausted.
46
47The `throttle.onSecondaryRateLimit` and `throttle.onRateLimit` options are required. Return `true` to automatically retry the request after `retryAfter` seconds.
48
49```js
50const MyOctokit = Octokit.plugin(throttling);
51
52const octokit = new MyOctokit({
53 auth: `secret123`,
54 throttle: {
55 onRateLimit: (retryAfter, options, octokit) => {
56 octokit.log.warn(
57 `Request quota exhausted for request ${options.method} ${options.url}`
58 );
59
60 if (options.request.retryCount === 0) {
61 // only retries once
62 octokit.log.info(`Retrying after ${retryAfter} seconds!`);
63 return true;
64 }
65 },
66 onSecondaryRateLimit: (retryAfter, options, octokit) => {
67 // does not retry, only logs a warning
68 octokit.log.warn(
69 `SecondaryRateLimit detected for request ${options.method} ${options.url}`
70 );
71 },
72 },
73});
74
75async function createIssueOnAllRepos(org) {
76 const repos = await octokit.paginate(
77 octokit.repos.listForOrg.endpoint({ org })
78 );
79 return Promise.all(
80 repos.map(({ name }) =>
81 octokit.issues.create({
82 owner,
83 repo: name,
84 title: "Hello, world!",
85 })
86 )
87 );
88}
89```
90
91Pass `{ throttle: { enabled: false } }` to disable this plugin.
92
93### Clustering
94
95Enabling Clustering support ensures that your application will not go over rate limits **across Octokit instances and across Nodejs processes**.
96
97First install either `redis` or `ioredis`:
98
99```
100# NodeRedis (https://github.com/NodeRedis/node_redis)
101npm install --save redis
102
103# or ioredis (https://github.com/luin/ioredis)
104npm install --save ioredis
105```
106
107Then in your application:
108
109```js
110const Bottleneck = require("bottleneck");
111const Redis = require("redis");
112
113const client = Redis.createClient({
114 /* options */
115});
116const connection = new Bottleneck.RedisConnection({ client });
117connection.on("error", err => console.error(err));
118
119const octokit = new MyOctokit({
120 auth: 'secret123'
121 throttle: {
122 onSecondaryRateLimit: (retryAfter, options, octokit) => {
123 /* ... */
124 },
125 onRateLimit: (retryAfter, options, octokit) => {
126 /* ... */
127 },
128
129 // The Bottleneck connection object
130 connection,
131
132 // A "throttling ID". All octokit instances with the same ID
133 // using the same Redis server will share the throttling.
134 id: "my-super-app",
135
136 // Otherwise the plugin uses a lighter version of Bottleneck without Redis support
137 Bottleneck
138 }
139});
140
141// To close the connection and allow your application to exit cleanly:
142await connection.disconnect();
143```
144
145To use the `ioredis` library instead:
146
147```js
148const Redis = require("ioredis");
149const client = new Redis({
150 /* options */
151});
152const connection = new Bottleneck.IORedisConnection({ client });
153connection.on("error", (err) => console.error(err));
154```
155
156## LICENSE
157
158[MIT](LICENSE)