Files
werkator/docs/plan/06-watcher.md
T

2.3 KiB

Step 06: Watcher and Scheduling

Prerequisites: steps 01, 02, 04. Read README.md and 00-legacy-analysis.md first.

Goal

Replace the legacy blocking main loop with a non-blocking, observable scheduler.

Design

Create package de.hoennig.gittally.watcher:

  • Watcher component with a fixed-delay poll cycle (Spring @Scheduled or a managed executor; enabled only in server/watch mode, not during CLI commands or tests).
  • One poll cycle, never blocking on a build:
    1. fetchOrigin() (errors: log, publish watcher health state, retry next cycle — no internal retry-sleep loops like legacy retry_origin_change_check).
    2. Determine candidate branches: changed local branches, plus new origin branches within watcher.newBranchMaxAge (step 02 operations).
    3. Check auto-build time slots (below).
    4. If the executor is idle, dequeue the next branch: checkout, reset to origin, startBuild (async).
    5. Run repository retention pruning and artifact pruning.
  • Startup sequence (port of legacy recovery): mark stale running builds interrupted, then enqueue restartable branches.
  • Auto-builds: per-branch autoBuild.enabled + times (UTC HH:MM) from the merged branches config. Persist "already triggered for slot/day" state via a small JSON file next to the build results (replaces auto-builds.tsv).
  • Expose watcher state (last poll time, last fetch error, queue) for the UI/status endpoints.

Out of Scope

  • HTTP endpoints (step 07); expose state via a service bean only.
  • Retry-failed-builds command (step 10 triggers it through the same queue).

Config

New key watcher.pollInterval (e.g. 10s, default matching legacy cadence). Update GitTallyConfig, InitCommand templates, and docs/configuration.md together.

Tests

  • Poll cycle unit tests with MockK: branch selection precedence, skip-when-building, fetch failure resilience.
  • Auto-build slot logic: slot matching, per-day dedup, state persistence.
  • New-branch age filtering.
  • Startup recovery: interrupted marking and re-enqueue (integration with steps 01/04 fakes).
  • No test may sleep for real poll intervals; trigger cycles directly.

Acceptance Criteria

  • ./gradlew ktlintFormat then ./gradlew build is green.
  • A test proves a poll cycle completes while a (fake) build is running.