Skip to content

Commit 1999287

Browse files
committed
feat: Add advanced cluster lifecycle management and dynamic scaling documentation
1 parent 890f8cc commit 1999287

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,76 @@ await gateway.listen(3000)
242242
console.log('Cluster started with 4 workers')
243243
```
244244

245+
#### Advanced usage: Cluster lifecycle and operations
246+
247+
Bungate’s cluster manager powers zero-downtime restarts, dynamic scaling, and safe shutdowns in production. You can control it via signals or programmatically.
248+
249+
- Zero-downtime rolling restart: send `SIGUSR2` to the master process
250+
- The manager spawns a replacement worker first, then gracefully stops the old one
251+
- Graceful shutdown: send `SIGTERM` or `SIGINT`
252+
- Workers receive `SIGTERM` and are given up to `shutdownTimeout` to exit before being force-killed
253+
254+
Programmatic controls (available when using the `ClusterManager` directly):
255+
256+
```ts
257+
import { ClusterManager, BunGateLogger } from 'bungate'
258+
259+
const logger = new BunGateLogger({ level: 'info' })
260+
261+
const cluster = new ClusterManager(
262+
{
263+
enabled: true,
264+
workers: 4,
265+
restartWorkers: true,
266+
restartDelay: 1000, // base delay used for exponential backoff with jitter
267+
maxRestarts: 10, // lifetime cap per worker
268+
respawnThreshold: 5, // sliding window cap
269+
respawnThresholdTime: 60_000, // within this time window
270+
shutdownTimeout: 30_000,
271+
// Set to false when embedding in tests to avoid process.exit(0)
272+
exitOnShutdown: true,
273+
},
274+
logger,
275+
'./gateway.ts', // worker entry (executed with Bun)
276+
)
277+
278+
await cluster.start()
279+
280+
// Dynamic scaling
281+
await cluster.scaleUp(2) // add 2 workers
282+
await cluster.scaleDown(1) // remove 1 worker
283+
await cluster.scaleTo(6) // set exact worker count
284+
285+
// Operational visibility
286+
console.log(cluster.getWorkerCount())
287+
console.log(cluster.getWorkerInfo()) // includes id, restarts, pid, etc.
288+
289+
// Broadcast a POSIX signal to all workers (e.g., for log-level reloads)
290+
cluster.broadcastSignal('SIGHUP')
291+
292+
// Target a single worker
293+
cluster.sendSignalToWorker(1, 'SIGHUP')
294+
295+
// Graceful shutdown (will exit process if exitOnShutdown !== false)
296+
// await (cluster as any).gracefulShutdown() // internal in gateway use; prefer SIGTERM
297+
```
298+
299+
Notes:
300+
- Each worker receives `CLUSTER_WORKER=true` and `CLUSTER_WORKER_ID=<n>` environment variables.
301+
- Restart policy uses exponential backoff with jitter and a sliding window threshold to prevent flapping.
302+
- Defaults: `shutdownTimeout` 30s, `respawnThreshold` 5 within 60s, `restartDelay` 1s, `maxRestarts` 10.
303+
304+
Configuration reference (cluster):
305+
- `enabled` (boolean): enable multi-process mode
306+
- `workers` (number): worker process count (defaults to CPU cores)
307+
- `restartWorkers` (boolean): auto-respawn crashed workers
308+
- `restartDelay` (ms): base delay for backoff
309+
- `maxRestarts` (number): lifetime restarts per worker
310+
- `respawnThreshold` (number): max restarts within time window
311+
- `respawnThresholdTime` (ms): sliding window size
312+
- `shutdownTimeout` (ms): grace period before force-kill
313+
- `exitOnShutdown` (boolean): if true (default), master exits after shutdown; set false in tests/embedded
314+
245315
### 🔄 **Advanced Load Balancing**
246316

247317
Distribute traffic intelligently across multiple backends:

0 commit comments

Comments
 (0)