Service sessions

Users close their own sessions. The orchestrator owns the container lifecycle. Reference counting keeps one user from disrupting another.

The shared-service problem

Two engineers are using pgAdmin at the same time. One finishes their work and clicks "Stop". Under a naive design, pgAdmin's container stops — kicking the other engineer out mid-query. This is the classic shared-resource race condition.

OrcheStack prevents this by separating user sessions from container lifecycle.

The design

Users do not stop services. They open and close their own sessions. Each session is a row in platform.service_sessions.

When a user clicks Open pgAdmin:

  1. OrcheStack checks their role's can_use + can_start.
  2. A session row is inserted with status=active.
  3. If the container isn't running, the Orchestrator spins it up.
  4. The user is redirected to /app/pgadmin.

When the user clicks End my session:

  1. Their session row is updated to status=closed.
  2. The orchestrator checks: are there any other active sessions for this service?
  3. If yes, the container keeps running.
  4. If no, an idle timer starts. After N minutes without a new session, the container is stopped.

Heartbeats and stale sessions

What if someone closes their laptop mid-session without clicking "End my session"? Their row would stay active forever, keeping the container alive.

Fix: heartbeats. The dashboard pings the session endpoint every 30 seconds while the user is on the page. A background job marks any session without a heartbeat for 5 minutes as stale. Stale sessions don't count.

Admin force-stop

Admins with can_force_stop=true can kill a container immediately, disconnecting all active sessions. This is intended for stuck or unresponsive services, not routine shutdown.

Every force-stop writes a row to platform.audit_log with the list of affected users. Admins answer for their overrides.

The UI guards the action with a confirmation dialog listing all users currently connected:

⚠  Force stop will disconnect 2 users from pgAdmin:
   •  engineer@acme.ng       — active for 14 min
   •  jane@acme.ng           — active for 3 min

   Use only for stuck or unresponsive services.
   All force-stop events are logged to the audit trail.