openvidu-dashboard: the graceful shutdown spec describes the drain

chore/update-openvidu-actions-1.0.25
juancarmore 2026-10-27 21:30:29 +01:00
parent 42605cfbf2
commit 5d99f6f379
5 changed files with 106 additions and 0 deletions

View File

@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-27

View File

@ -0,0 +1,27 @@
# Design
## Context
- On the first `SIGINT`, `SIGTERM` or `SIGQUIT` the server calls `Stop(false)`: it drains the router and waits, every
5 s, until it has no participants. A second signal calls `Stop(true)`, which does not wait; the server then closes
its rooms with `SERVER_SHUTDOWN` and `openvidu.Stop` flushes telemetry and the analytics queues for at most 5 s.
- `docker-compose down` sends one `SIGTERM` and kills the container after its stop grace period.
## Goals / Non-Goals
**Goals:**
- The spec says what a planned stop and a forced stop leave in the store.
**Non-Goals:**
- Closing rooms on the first signal, which would cut the graceful drain of media nodes.
## Decisions
### Describe the drain
The drain is the server's contract with clients and with the scale-in of media nodes; the analytics writer follows it.
The requirement now covers the drain, the second signal and the kill during the drain.
### Data model
- No change.

View File

@ -0,0 +1,39 @@
# Proposal
## Why
The "Graceful shutdown" requirement says that on `SIGTERM` a node with active rooms closes them with `SERVER_SHUTDOWN`
and flushes their end. The server does not do that: the first `SIGTERM` drains it (no new participants, wait for the
present ones to leave) and only a second signal closes the rooms. A forced stop of a node (`docker-compose down`, which
kills it after its grace period) therefore ends while it drains, writes nothing more, and the reconciler closes its
sessions as for a crashed node. The integration test of that case expects leave events and fails.
## What Changes
- The requirement describes the drain: during it the participants that leave are written as usual; a second signal
closes the rooms with `SERVER_SHUTDOWN`; once the rooms are closed, the flush works as before.
- A node killed while it drains is left to the reconciler, as a crashed one.
- No server or writer behaviour changes.
Scope excludes the following:
- The drain itself and the stop of media nodes in the deployments.
Edition: CE and PRO (server). Repositories: the specs of the dashboard, and the end-to-end reconciler tests of the
deployments (forced media node stop).
CHANGELOG: none.
## Capabilities
### New Capabilities
None.
### Modified Capabilities
- `server-analytics-writer`: "Graceful shutdown" describes the drain and the forced stop.
## Impact
- Specs only, and the forced media node stop case of the end-to-end reconciler tests, which now expects the
reconciler to close the sessions of a node stopped by force.

View File

@ -0,0 +1,24 @@
## MODIFIED Requirements
### Requirement: Graceful shutdown
Edition: CE and PRO. On a first `SIGTERM` or `SIGINT` the server drains: it takes no new participants and waits for
the present ones to leave, whose leave events are written as usual; a second signal closes the rooms with
`SERVER_SHUTDOWN`. Once the rooms are closed the server SHALL flush the telemetry stats workers and operation queue
into the writer and write every queued event and stat before exiting, waiting at most 5 s; entries not written in that
window SHALL be counted as dropped. A node killed while it drains writes nothing more and its open sessions are left
to the reconciler.
#### Scenario: Planned restart
- **GIVEN** a node with active rooms and participants
- **WHEN** it receives `SIGTERM` and then a second `SIGTERM`
- **THEN** the database holds the `ROOM_ENDED (ROOM_END_SERVER_SHUTDOWN)` and `PARTICIPANT_LEFT` events and the entities are `closed`/`left` with the final stats flushed
#### Scenario: Killed while draining
- **GIVEN** a node with active participants that receives one `SIGTERM`
- **WHEN** it is killed before they leave, as `docker-compose down` does after its grace period
- **THEN** no end event of those sessions is written and the reconciler closes them as for a crashed node, with `closedBy: "reconciler"`
#### Scenario: Database unavailable at shutdown
- **GIVEN** an unreachable database
- **WHEN** the node receives `SIGTERM`
- **THEN** the process exits within 5 s of the signal and logs the number of dropped entries

View File

@ -0,0 +1,14 @@
# Tasks
## 1. Tests
- [ ] 1.1 Make the forced media node stop case of the end-to-end reconciler tests expect the reconciler to close the
sessions of the node. Verify by running it on the deployment playground.
## 2. Docs and CHANGELOG
- [x] 2.1 No CHANGELOG line and no `AGENTS.md` change. Verify by reading the change against both.
## 3. Integration check
- [x] 3.1 Run the spec validation and the format check of the dashboard. Verify that they pass.