mirror of
https://github.com/JonasunderscoreJones/api-worker.git
synced 2025-10-23 10:29:19 +02:00
Initial commit (by create-cloudflare CLI)
This commit is contained in:
commit
58a42872a0
1745 changed files with 741893 additions and 0 deletions
21
node_modules/stoppable/LICENSE
generated
vendored
Normal file
21
node_modules/stoppable/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Hunter Loftis <hunter@hunterloftis.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
65
node_modules/stoppable/lib/stoppable.js
generated
vendored
Normal file
65
node_modules/stoppable/lib/stoppable.js
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
'use strict'
|
||||
|
||||
const https = require('https')
|
||||
|
||||
module.exports = (server, grace) => {
|
||||
grace = typeof grace === 'undefined' ? Infinity : grace
|
||||
const reqsPerSocket = new Map()
|
||||
let stopped = false
|
||||
let gracefully = true
|
||||
|
||||
if (server instanceof https.Server) {
|
||||
server.on('secureConnection', onConnection)
|
||||
} else {
|
||||
server.on('connection', onConnection)
|
||||
}
|
||||
|
||||
server.on('request', onRequest)
|
||||
server.stop = stop
|
||||
server._pendingSockets = reqsPerSocket
|
||||
return server
|
||||
|
||||
function onConnection (socket) {
|
||||
reqsPerSocket.set(socket, 0)
|
||||
socket.once('close', () => reqsPerSocket.delete(socket))
|
||||
}
|
||||
|
||||
function onRequest (req, res) {
|
||||
reqsPerSocket.set(req.socket, reqsPerSocket.get(req.socket) + 1)
|
||||
res.once('finish', () => {
|
||||
const pending = reqsPerSocket.get(req.socket) - 1
|
||||
reqsPerSocket.set(req.socket, pending)
|
||||
if (stopped && pending === 0) {
|
||||
req.socket.end()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function stop (callback) {
|
||||
// allow request handlers to update state before we act on that state
|
||||
setImmediate(() => {
|
||||
stopped = true
|
||||
if (grace < Infinity) {
|
||||
setTimeout(destroyAll, grace).unref()
|
||||
}
|
||||
server.close(e => {
|
||||
if (callback) {
|
||||
callback(e, gracefully)
|
||||
}
|
||||
})
|
||||
reqsPerSocket.forEach(endIfIdle)
|
||||
})
|
||||
}
|
||||
|
||||
function endIfIdle (requests, socket) {
|
||||
if (requests === 0) socket.end()
|
||||
}
|
||||
|
||||
function destroyAll () {
|
||||
gracefully = false
|
||||
reqsPerSocket.forEach((reqs, socket) => socket.end())
|
||||
setImmediate(() => {
|
||||
reqsPerSocket.forEach((reqs, socket) => socket.destroy())
|
||||
})
|
||||
}
|
||||
}
|
49
node_modules/stoppable/package.json
generated
vendored
Normal file
49
node_modules/stoppable/package.json
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "stoppable",
|
||||
"version": "1.1.0",
|
||||
"engines": {
|
||||
"node": ">=4",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"keywords": [
|
||||
"server",
|
||||
"net",
|
||||
"connect",
|
||||
"socket",
|
||||
"connection",
|
||||
"stop",
|
||||
"close",
|
||||
"disconnect",
|
||||
"disconnection",
|
||||
"http",
|
||||
"https",
|
||||
"tcp"
|
||||
],
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hunterloftis/stoppable.git"
|
||||
},
|
||||
"homepage": "https://github.com/hunterloftis/stoppable",
|
||||
"scripts": {
|
||||
"lint": "standard --fix \"lib/**/*.js\" \"test/**/*.js\"",
|
||||
"spec": "nyc --check-coverage mocha --bail \"test/*.test.js\"",
|
||||
"test": "npm run lint && npm audit && npm run spec",
|
||||
"coverage": "nyc mocha --bail \"test/*.test.js\"",
|
||||
"perf:baseline": "node test/performance.js & sleep 2 && artillery quick -d 10 -r 1000 -o /dev/null -k http://localhost:8000",
|
||||
"perf:stoppable": "node test/performance.js 1 & sleep 2 && artillery quick -d 10 -r 1000 -o /dev/null -k http://localhost:8000"
|
||||
},
|
||||
"main": "lib/stoppable.js",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"artillery": "^1.6.0-15",
|
||||
"awaiting": "^3.0.0",
|
||||
"chai": "^4.1.2",
|
||||
"mocha": "^5.0.5",
|
||||
"nyc": "^11.6.0",
|
||||
"requisition": "^1.7.0",
|
||||
"standard": "^11.0.1"
|
||||
}
|
||||
}
|
127
node_modules/stoppable/readme.md
generated
vendored
Normal file
127
node_modules/stoppable/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Stoppable
|
||||
|
||||
[](https://travis-ci.org/hunterloftis/stoppable)
|
||||
|
||||
> Node's `server.close()` the way you probably [expected it to work by default](https://github.com/nodejs/node/issues/2642).
|
||||
|
||||
## Summary
|
||||
|
||||
```js
|
||||
const server = stoppable(http.createServer(handler))
|
||||
server.stop()
|
||||
```
|
||||
|
||||
Stoppable stops accepting new connections and closes existing, idle connections (including keep-alives)
|
||||
without killing requests that are in-flight.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js v6+
|
||||
|
||||
Node.js v4.x is *unofficially* supported.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add stoppable
|
||||
```
|
||||
|
||||
(or use npm)
|
||||
|
||||
## Usage
|
||||
|
||||
**constructor**
|
||||
|
||||
```js
|
||||
stoppable(server, grace)
|
||||
```
|
||||
|
||||
Decorates the server instance with a `stop` method.
|
||||
Returns the server instance, so can be chained, or can be run as a standalone statement.
|
||||
|
||||
- server: Any HTTP or HTTPS Server instance
|
||||
- grace: Milliseconds to wait before force-closing connections
|
||||
|
||||
`grace` defaults to Infinity (don't force-close).
|
||||
If you want to immediately kill all sockets you can use a grace of 0.
|
||||
|
||||
**stop()**
|
||||
|
||||
```js
|
||||
server.stop(callback)
|
||||
```
|
||||
|
||||
Closes the server.
|
||||
|
||||
- callback: passed along to the existing `server.close` function to auto-register a 'close' event.
|
||||
The first agrument is an error, and the second argument is a boolean that indicates whether it stopped gracefully.
|
||||
|
||||
## Design decisions
|
||||
|
||||
- Monkey patching generally sucks, but in this case it's the nicest API. Let's call it "decorating."
|
||||
- `grace` could be specified on `stop`, but it's better to match the existing `server.close` API.
|
||||
- Clients should be handled respectfully, so we aren't just destroying sockets, we're sending `FIN` packets first.
|
||||
- Any solution to this problem requires bookkeeping on every connection and request/response.
|
||||
We're doing a minimum of work on these "hot" code paths and delaying as much as possible to the actual `stop` method.
|
||||
|
||||
## Performance
|
||||
|
||||
There's no way to provide this functionality without bookkeeping on connection, disconnection, request, and response.
|
||||
However, Stoppable strives to do minimal work in hot code paths and to use optimal data structures.
|
||||
|
||||
I'd be interested to see real-world performance benchmarks;
|
||||
the simple loopback artillery benchmark included in the lib shows very little overhead from using a stoppable server:
|
||||
|
||||
### Without Stoppable
|
||||
|
||||
```plain
|
||||
Scenarios launched: 10000
|
||||
Scenarios completed: 10000
|
||||
Requests completed: 10000
|
||||
RPS sent: 939.85
|
||||
Request latency:
|
||||
min: 0.5
|
||||
max: 51.3
|
||||
median: 2.1
|
||||
p95: 3.7
|
||||
p99: 15.3
|
||||
Scenario duration:
|
||||
min: 1
|
||||
max: 60.7
|
||||
median: 3.6
|
||||
p95: 7.6
|
||||
p99: 19
|
||||
Scenario counts:
|
||||
0: 10000 (100%)
|
||||
Codes:
|
||||
200: 10000
|
||||
```
|
||||
|
||||
### With Stoppable
|
||||
|
||||
```plain
|
||||
Scenarios launched: 10000
|
||||
Scenarios completed: 10000
|
||||
Requests completed: 10000
|
||||
RPS sent: 940.73
|
||||
Request latency:
|
||||
min: 0.5
|
||||
max: 43.4
|
||||
median: 2.1
|
||||
p95: 3.8
|
||||
p99: 15.5
|
||||
Scenario duration:
|
||||
min: 1.1
|
||||
max: 57
|
||||
median: 3.7
|
||||
p95: 8
|
||||
p99: 19.4
|
||||
Scenario counts:
|
||||
0: 10000 (100%)
|
||||
Codes:
|
||||
200: 10000
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
Loading…
Add table
Add a link
Reference in a new issue