Skip to content
This repository has been archived by the owner on Oct 19, 2023. It is now read-only.

Commit

Permalink
Use response headers to check API limit
Browse files Browse the repository at this point in the history
  • Loading branch information
AustinLeeGordon committed Jan 14, 2019
1 parent 2f59d0b commit 76e937e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 28 deletions.
2 changes: 1 addition & 1 deletion contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Before submitting a pull request, please make sure the following is done:
1. Fork the repository and create your branch from master.
2. Run `npm build`. This will:
1. Run `npm install` in the repository root.
2. Ensure the test suite passes with`npm test`.
2. Ensure the test suite passes with `npm test`.
3. Format your code with prettier and eslint using `npm run lint`.
3. If you’ve fixed a bug or added code that should be tested, add tests!

Expand Down
73 changes: 46 additions & 27 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class Client extends EventEmitter {
params.auth = this.auth
}
params.json = true
params.resolveWithFullResponse = true

params.url = this.baseUrl + params.path
delete params.path
Expand All @@ -123,38 +124,56 @@ class Client extends EventEmitter {

return this.checkApiLimit(params).then(() => {
this.emit('apiCall', params)
return limiter.schedule(() => request(params)) // limit the number of concurrent requests
return limiter.schedule(() =>
request(params)
.then(res => {
this.updateApiLimit(res)
return res
})
.then(res => res.body),
) // limit the number of concurrent requests
})
}

checkApiLimit(params) {
if (this.auth) {
// don't check the api limit for the api call
return Promise.resolve()
}
if (/integrations\/v1\/limit|oauth/.test(params.url)) {
// don't check the api limit for the api call
return Promise.resolve()
updateApiLimit(res) {
const { headers } = res
if (this.usageLimit === undefined) {
this.usageLimit = headers['x-hubspot-ratelimit-daily']
}
if (!this.checkLimit) {
// don't check the api limit for the api call
return Promise.resolve()
}
if (this.maxUsePercent === 0) {
// if maxUsePercent set to 0, do not check for the API limit (use at your own risk)
return Promise.resolve()
}
return this.getApiLimit().then(results => {
const { usageLimit = 40000, currentUsage = 0 } = results
const usagePercent = (100.0 * currentUsage) / usageLimit
debug('usagePercent', usagePercent, 'apiCalls', this.apiCalls)
if (usagePercent > this.maxUsePercent) {
const err = new Error('Too close to the API limit')
err.usageLimit = usageLimit
err.currentUsage = currentUsage
err.usagePercent = usagePercent
throw err
this.currentUsage = headers['x-hubspot-ratelimit-daily-remaining']
return Promise.resolve()
}

checkApiLimit(params) {
return new Promise((resolve, reject) => {
if (this.auth) {
// don't check the api limit for the api call
resolve()
}
if (/integrations\/v1\/limit|oauth/.test(params.url)) {
// don't check the api limit for the api call
resolve()
}
if (!this.checkLimit) {
// don't check the api limit for the api call
resolve()
}
if (this.maxUsePercent === 0) {
// if maxUsePercent set to 0, do not check for the API limit (use at your own risk)
resolve()
}
if (this.currentUsage !== undefined) {
const usagePercent = (100.0 * this.currentUsage) / this.usageLimit
debug('usagePercent', usagePercent, 'apiCalls', this.apiCalls)
if (usagePercent > this.maxUsePercent) {
const err = new Error('Too close to the API limit')
err.usageLimit = this.usageLimit
err.currentUsage = this.currentUsage
err.usagePercent = usagePercent
reject(err)
}
}
resolve()
})
}

Expand Down

0 comments on commit 76e937e

Please sign in to comment.