-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from jokester/revise-demo
Revise demo
- Loading branch information
Showing
14 changed files
with
134 additions
and
5,203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
# Dockerfile for demo | ||
# or, FROM node:18-alpine | ||
FROM node:18-bookworm-slim | ||
|
||
COPY . /opt/publicaddr | ||
|
||
RUN set -uex \ | ||
&& cd /opt/publicaddr/demo \ | ||
&& npm i \ | ||
&& npm i -g publicaddr@0.4.3 \ | ||
&& npm cache clean --force | ||
|
||
COPY ./demo-server.mjs /opt/demo-server.mjs |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import http from 'node:http'; | ||
const wait = timeout => new Promise(f => setTimeout(f, timeout)) | ||
const waitRandom = (min, max) => wait(min + Math.random() * (max - min)) | ||
|
||
const processTag = `demo-server-version-${process.env.VERSION ?? '?'}-${Math.random().toString(16).slice(2, 10)}` | ||
|
||
let reqCount = 0 | ||
let onFlight = 0 | ||
|
||
const server = http.createServer(async (req, res) => { | ||
++onFlight; | ||
res.writeHead(200, undefined, | ||
// { connection: 'Close' } | ||
); | ||
await waitRandom(20, 100); | ||
res.end(`reqCount: ${++reqCount} from ${processTag}`) | ||
--onFlight; | ||
}) | ||
|
||
function log(...args) { | ||
console.info(`${Date.now().toFixed(2)} ${processTag}:`, ...args) | ||
} | ||
|
||
async function waitRequestsEnd() { | ||
while (onFlight > 0) { | ||
await wait(1e3) | ||
} | ||
} | ||
|
||
function startReportCount() { | ||
let lastReqCountReported = 0 | ||
const interval = 10 // s | ||
const timer = setInterval(() => { | ||
const delta = reqCount - lastReqCountReported | ||
lastReqCountReported = reqCount | ||
log(`reqCount: ${reqCount}`); | ||
log(`mean RPS: ${(delta / interval).toFixed(2)}`); | ||
}, interval * 1e3) | ||
return () => clearInterval(timer) | ||
} | ||
|
||
async function main() { | ||
const port = Number(process.env.PORT || 3000) | ||
const gotSignal = new Promise((resolve, reject) => { | ||
process.on('SIGINT', resolve) | ||
process.on('SIGTERM', resolve) | ||
}) | ||
const stopReportCount = startReportCount() | ||
|
||
server.listen(port, () => { | ||
log(`listening on port ${port}`) | ||
}) | ||
await gotSignal | ||
const error = await new Promise(f => server.close(f)) | ||
if (error) { | ||
console.error('server close error:', error) | ||
} | ||
stopReportCount() | ||
log(`app closing.`) | ||
} | ||
|
||
await main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,26 @@ | ||
version: "3" | ||
services: | ||
demo-server-g1: &demo-server | ||
# build: | ||
# context: .. | ||
# dockerfile: demo/Dockerfile | ||
# dockerfile: demo/Dockerfile-alpine | ||
image: ${SLOT1_IMAGE} | ||
command: npm start | ||
working_dir: /opt/publicaddr/demo | ||
# see https://iximiuz.com/en/posts/multiple-containers-same-port-reverse-proxy/ for explanation | ||
sandbox: | ||
image: alpine | ||
command: sleep infinity | ||
ports: | ||
- 3000:3000 | ||
|
||
demo-server-a: &demo-server | ||
build: . | ||
command: publicaddr node /opt/demo-server.mjs | ||
network_mode: service:sandbox | ||
environment: | ||
VERSION: 'a' | ||
deploy: | ||
replicas: ${SLOT1_REPLICA:-4} | ||
# NOTE I have no idea how to get default network_mode (requires port mapping) + replica working | ||
# network_mode=host (and perhaps some other) works with SO_REUSEPORT | ||
network_mode: host | ||
replicas: ${VERSION_A_REPLICA:-4} | ||
|
||
# with publicaddr one can even do zero-downtime rollout | ||
# | ||
# e.g. | ||
# 0. Start with g1.replica=6 g2.replica=0 # Users only see reply from g1 | ||
# 1. Set new image in g2 | ||
# 2. Set g1.replicas=3 g1.replicas=3 | ||
# 3. docker-compose up -d # user starts to see reply from g1 / g2 | ||
# 4. Set g1.replicas=0 g2.replicas=6 | ||
# 5. docker-compose up -d # user starts to see reply from g2 | ||
demo-server-g2: | ||
<<: *demo-server | ||
image: ${SLOT2_IMAGE} | ||
demo-server-b: &demo-server | ||
build: . | ||
command: publicaddr node /opt/demo-server.mjs | ||
network_mode: service:sandbox | ||
environment: | ||
VERSION: 'b' | ||
deploy: | ||
replicas: ${SLOT2_REPLICA:-0} | ||
replicas: ${VERSION_B_REPLICA:-0} |
Oops, something went wrong.