WiseHosting
Architecture

Data flow

What happens when a user deploys an app — end-to-end traces.

This page traces what happens when a user deploys an app.

How to read the diagrams

Each sequence diagram is a chronological story: each arrow is one network call from left to right. Solid arrows are synchronous (the sender waits); dashed arrows are fire-and-forget. The participant names match the code — HUB is internal/api/ws.go's Hub, SCH is internal/scheduler, W is the internal/worker agent, and so on.

1. Deploy

2. Live container metrics

Snapshots live in process memory and expire after 45 s; misses return live=false.

3. Runtime logs

Each line is sanitised (stripANSI + null byte removal) and capped to 8 KiB before reaching the bus.

4. Worker health

If a worker drops, the scheduler:

  1. Marks it offline.
  2. Stops all running apps assigned to it (status cascade).
  3. Pending jobs queued for that worker remain assigned until recoverStuckJobs (15-min timeout) flips them to failed. Failures are not retried automatically — the job stays failed and surfaces to the user, who can redeploy (the in-process requeueFailedJobs loop and max_retries/retry_count columns were removed in migration 0004 so a worker outage no longer multiplies into N silent re-runs once it returns).

5. Push events (auto-deploy)

Each provider has its own header & secret style:

ProviderHeaderAlgorithm
GitHubX-Hub-Signature-256HMAC-SHA256 of body
CodebergX-Gitea-SignatureHMAC-SHA256 of body
GitLabX-Gitlab-Tokenshared-token equality
BitbucketX-Hub-Signature (sha256=)HMAC-SHA256 of body

6. Alert evaluation (per-app rules)

The poller walks every enabled rule across every app on each tick. A rule fires only after the metric stays over threshold for sustain_minutes, and resolves only after the same window elapses below the threshold — both edges debounced. Event-driven kinds (offline, crashloop, deployment_failed) skip the threshold check and fire/resolve directly off the underlying state change.

7. Usage time-series

Recorder writes one row per (app_id, 5-min bucket) per minute (last write wins for the same bucket). A daily pruner deletes rows older than 90 days. The endpoint never reads raw samples beyond that window.

8. Custom-domain routing

internal/api/traefik.go is the Traefik HTTP-provider endpoint. The worker's local Traefik polls it every 2 s with the same JWT it uses for WSS; the response is a flat {routers, services} JSON document keyed by safeRouterName(app.Name). buildHostRule joins the app's verified hostnames with ||, so a single app can serve any number of custom domains plus its <sub>.wisehost.in apex without router duplication.

On this page