Project challenges / verified progress
Engineering project paths

The engineering notebook

Beacon: turn a program into a service

You finish able to build a local Go service that schedules checks, loads validated configuration, stores recent and durable results, serves a versioned JSON API, writes structured logs, reports health truthfully and exits cleanly on SIGTERM.

Your learning trail

0 / 10 complete

Verified project-agent submissions only. Reading or clicking cannot unlock progress.

System design

What you are building

The service wraps the Course 1 prober in process machinery: a scheduler chooses when checks run, configuration decides what to watch, stores keep results in memory and SQLite, an HTTP API exposes versioned JSON, structured logs describe every important event, and shutdown plus health endpoints make the process understandable to supervisors.

BEACON / THE SERVICEThe clockevery interval, foreverTHE SERVICE YOU OWNSchedulerticks, jitter, no driftProbercourse one, unchangedStorering buffer, then SQLiteHTTP APIJSON a client can rely onOUTSIDE YOUR PROCESSTargets filethe list to watchSIGTERMfinish, then exitshutdown drains in-flight checks before the process exitsA PROGRAM YOU RUN BECOMES A SERVICE THAT RUNS ITSELF

Stages

10 stages, in order

Expand any stage to read what it teaches. A stage opens for work once the stage before it passes a verified submission.

Phase 1Stages 1–20 of 2 stages verified

Phase 1 — Time and input

Run checks on a reliable cadence and decide what to watch from validated configuration.

  • Run checks on schedule75 minutes (locked)

    How does a service repeat work without lying about time?

    You will be able to add an internal/scheduler package with a Run function that accepts a context, interval, jitter window and check function.

    Fork the project repository to start working through the stages.

  • Load targets from config90 minutes (locked)

    How does a service know what to watch before it starts watching?

    You will be able to create an internal/config package with a Load function that returns one resolved Config value.

    Fork the project repository to start working through the stages.

Phase 2Stages 3–40 of 2 stages verified

Phase 2 — Memory and history

Keep recent results safely in memory, then persist durable history in a local SQLite database.

  • Keep recent results90 minutes (locked)

    How can concurrent checks share results without corrupting memory?

    You will be able to create internal/store/memory.go with an in-memory store for prober results.

    Fork the project repository to start working through the stages.

  • Persist results in SQLite2 hours (locked)

    How does Beacon remember checks after the process restarts?

    You will be able to add internal/store/sqlite.go using database/sql and modernc.org/sqlite.

    Fork the project repository to start working through the stages.

Phase 3Stages 5–70 of 3 stages verified

Phase 3 — API and observability

Expose versioned JSON over HTTP and produce structured logs operators can search during incidents.

  • Expose results over HTTP90 minutes (locked)

    How should a Go service expose stored data without turning every error into 200 OK?

    You will be able to create internal/api with routes for GET /v1/results and GET /v1/results/{target}.

    Fork the project repository to start working through the stages.

  • Shape the JSON contract75 minutes (locked)

    Why is an API response a promise rather than whatever your structs look like today?

    You will be able to create explicit API response types for result lists, errors and version output.

    Fork the project repository to start working through the stages.

  • Write machine-readable logs75 minutes (locked)

    How do logs help during an incident without leaking what they should not?

    You will be able to create logging setup that chooses text or JSON handler from resolved config.

    Fork the project repository to start working through the stages.

Phase 4Stages 8–100 of 3 stages verified

Phase 4 — Process behaviour

Shut down politely, report health truthfully and build one stamped service binary.

  • Shut down politely90 minutes (locked)

    What should happen between SIGTERM and the process actually exiting?

    You will be able to use signal.NotifyContext in cmd/beacond for SIGINT and SIGTERM.

    Fork the project repository to start working through the stages.

  • Tell health truthfully75 minutes (locked)

    What should `/healthz` and `/readyz` actually answer?

    You will be able to add GET /healthz returning 200 when the process is alive.

    Fork the project repository to start working through the stages.

  • Build one service binary90 minutes (locked)

    How do all the pieces become one artifact an operator can run?

    You will be able to produce bin/beacond with go build -o bin/beacond ./cmd/beacond.

    Fork the project repository to start working through the stages.

About this path

A prober can answer one question. A service must keep asking, remember the answers, expose them safely, explain itself in logs, and shut down without tearing work in half. This course turns the useful program into a process an operator can trust.

What you will learn: Go scheduler and tickers, SQLite persistence in Go, net/http JSON API design, Structured logging with slog, Graceful shutdown and signals. Build the project through cumulative challenges with beginner explanations and local verification.

Level
Complete beginner to independently building and operating the project
Format
10 cumulative stages. Every stage teaches the concept in full before any code, then gives you the thing to build and the run that proves it works
Before you start
Go 1.22 or newer, a terminal and Git. Everything runs locally and free. No cloud account, no credentials and no hosted database are required.
Official documentation (opens in a new tab)