UNPKG

4.49 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[![Greenkeeper](https://badges.greenkeeper.io/octokit/plugin-throttling.js.svg)](https://greenkeeper.io/)
8
9Implements all [recommended best practises](https://developer.github.com/v3/guides/best-practices-for-integrators/) to prevent hitting abuse rate limits.
10
11## Usage
12
13<table>
14<tbody valign=top align=left>
15<tr><th>
16Browsers
17</th><td width=100%>
18
19Load `@octokit/plugin-throttling` and [`@octokit/core`](https://github.com/octokit/core.js) (or core-compatible module) directly from [cdn.pika.dev](https://cdn.pika.dev)
20
21```html
22<script type="module">
23 import { Octokit } from "https://cdn.pika.dev/@octokit/core";
24 import { throttling } from "https://cdn.pika.dev/@octokit/plugin-throttling";
25</script>
26```
27
28</td></tr>
29<tr><th>
30Node
31</th><td>
32
33Install with `npm install @octokit/core @octokit/plugin-throttling`. Optionally replace `@octokit/core` with a core-compatible module
34
35```js
36const { Octokit } = require("@octokit/core");
37const { throttling } = require("@octokit/plugin-throttling");
38```
39
40</td></tr>
41</tbody>
42</table>
43
44The 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.
45
46The `throttle.onAbuseLimit` and `throttle.onRateLimit` options are required. Return `true` to automatically retry the request after `retryAfter` seconds.
47
48```js
49const MyOctokit = Octokit.plugin(throttling);
50const octokit = new MyOctokit({ auth: "secret123" });
51
52const octokit = new MyOctokit({
53 auth: `secret123`,
54 throttle: {
55 onRateLimit: (retryAfter, options) => {
56 console.warn(`Request quota exhausted for request ${options.method} ${options.url}`)
57
58 if (options.request.retryCount === 0) { // only retries once
59 console.log(`Retrying after ${retryAfter} seconds!`)
60 return true
61 }
62 },
63 onAbuseLimit: (retryAfter, options) => {
64 // does not retry, only logs a warning
65 console.warn(`Abuse detected for request ${options.method} ${options.url}`)
66 }
67 }
68})
69
70async function createIssueOnAllRepos (org) {
71 const repos = await octokit.paginate(octokit.repos.listForOrg.endpoint({ org }))
72 return Promise.all(repos.forEach(({ name } => {
73 octokit.issues.create({
74 owner,
75 repo: name,
76 title: 'Hello, world!'
77 })
78 })))
79}
80```
81
82Pass `{ throttle: { enabled: false } }` to disable this plugin.
83
84### Clustering
85
86Enabling Clustering support ensures that your application will not go over rate limits **across Octokit instances and across Nodejs processes**.
87
88First install either `redis` or `ioredis`:
89
90```
91# NodeRedis (https://github.com/NodeRedis/node_redis)
92npm install --save redis
93
94# or ioredis (https://github.com/luin/ioredis)
95npm install --save ioredis
96```
97
98Then in your application:
99
100```js
101const Bottleneck = require("bottleneck");
102const Redis = require("redis");
103
104const client = Redis.createClient({
105 /* options */
106});
107const connection = new Bottleneck.RedisConnection({ client });
108connection.on("error", err => console.error(err));
109
110const octokit = new MyOctokit({
111 auth: 'secret123'
112 throttle: {
113 onAbuseLimit: (retryAfter, options) => {
114 /* ... */
115 },
116 onRateLimit: (retryAfter, options) => {
117 /* ... */
118 },
119
120 // The Bottleneck connection object
121 connection,
122
123 // A "throttling ID". All octokit instances with the same ID
124 // using the same Redis server will share the throttling.
125 id: "my-super-app",
126
127 // Otherwise the plugin uses a lighter version of Bottleneck without Redis support
128 Bottleneck
129 }
130});
131
132// To close the connection and allow your application to exit cleanly:
133await connection.disconnect();
134```
135
136To use the `ioredis` library instead:
137
138```js
139const Redis = require("ioredis");
140const client = new Redis({
141 /* options */
142});
143const connection = new Bottleneck.IORedisConnection({ client });
144connection.on("error", err => console.error(err));
145```
146
147## LICENSE
148
149[MIT](LICENSE)