net/go.book
Marketing

Study route · Scalable notifications

Interview prep

A focused route through the reading and exercises for a notification-system design interview, with networking follow-ups for the App Connector discussion.

Start here if time is short. Read the first three topics. Then try HTTP cancellation and the chat-server slow-consumer experiment. For each choice, explain its cost, one failure scenario, and the requirement that would make you change it.

Main reading, in priority order

The interview update mentions delivering notifications to users, including configuration changes and events. Begin with the delivery contract and the recipient before choosing a transport.

  1. Notifications, SSE, and real-time updates

    Study transport choice, reconnects, replay, slow subscribers, and delivery across multiple server instances.

    Explain: Do recipients need the latest state or every event? When would you choose polling, SSE, WebSockets, or webhooks?

  2. Background jobs and task queues

    Study durable work, bounded worker concurrency, asynchronous response contracts, backlog monitoring, and recovery.

    Explain: What survives a restart? What does an accepted response promise? What if the worker finishes the effect but crashes before acknowledging it?

  3. Webhooks and event-driven design

    Study signatures over the raw body, ambiguous timeouts, duplicate delivery, retries, payload versions, and subscriptions.

    Explain: What if processing succeeded but the response was lost? Which operations must be atomic for a retry to be safe?

  4. Bounded worker pools and context cancellation

    Study concurrency limits, overload, deadlines, goroutine ownership, and shutdown.

    Explain: Where does excess work wait? Who stops it? How do you prove a worker has exited after cancellation?

  5. Dynamic configuration

    Study periodic refresh and local snapshots, then reason about push updates, versions, ordering, and resynchronization.

    Explain: Should a notification carry the new state or tell a client to fetch it? How stale may configuration become?

  6. Distributed rate limiting

    Study limits shared across replicas, per-customer budgets, and downstream protection.

    Explain: How do you keep one tenant or slow endpoint from consuming everyone's workers? Which limits apply to requests, queued work, and active sends?

Networking follow-ups

Use these to strengthen the address-mapping and stale-state discussion. Keep the main study effort on notification design.

DNS and caching

What happens when a mapping changes while clients retain the old DNS answer? Connect cache lifetime to address reuse.

TCP versus UDP

Separate transport reliability from application processing. Receiving bytes does not establish a durable business effect.

Exercises to turn into failure experiments

The source links open the actual exercise files in the browser. The changes and experiments below are suggested extensions; they are not already implemented. The standalone exercises cover Part 2. The SSE and webhook examples are in the chapters above.

  1. HTTP cancellation and an uncertain result

    Point the client at http://127.0.0.1:8083/. Give it a timeout shorter than the server's five-second wait. Log cancellation on the server; its existing cancellation branch tries to write to a client that may already be gone.

    Next, model an effect that finishes before the reply reaches the client. Discuss what a retry could repeat.

    Be ready to answer: Does a timeout prove the operation failed? What additional evidence would make retrying safe?

  2. Notification fan-out and a slow subscriber

    Connect two clients. Add a delay to one client's server-side writer and send a burst. The basic server has a buffer of 16 messages per client and removes clients whose buffer fills. Choose a policy: drop events, disconnect slow clients, or retain events for replay.

    Compare the advanced server, which writes to sockets sequentially while holding the client mutex. Trace what a blocked write does to the other clients. Also inspect cleanup: the basic server's normal disconnect path does not close its send channel, so an idle writer can remain waiting.

    Be ready to answer: How do you isolate one slow recipient, and how does it recover missed notifications?

  3. Bound concurrent work

    The server listens on port 9000 and starts a goroutine for each connection. Open several connections that send nothing. Add a small concurrency limit and a read deadline, then decide whether excess clients wait or are rejected.

    Be ready to answer: Where does overload accumulate, and what resource does each limit protect?

  4. Graceful shutdown during delivery

    Add a slow handler. Stop the server while requests are running. Repeat with a handler that takes longer than the 15-second shutdown budget. Observe which work finishes and which work needs a durable record for recovery.

    Be ready to answer: What happens to in-flight notifications during deployment? What happens when graceful shutdown is impossible?

  5. DNS caching and stale addresses

    Substitute a controllable lookup function. Change its answer while the previous result remains cached, then expire the entry. The example uses fixed 60-second success and five-second failure durations; it does not obtain those TTLs from DNS.

    Be ready to answer: Who may still use the old address after its mapping changes? What makes reuse safe?

Optional: delayed health detection

Open the load balancer source. Use two local backends with /health endpoints, then stop one. Observe requests before the next health result. The balancer listens on 9600; it checks backends sequentially, then sleeps five seconds.

How stale can a health observation become? Does a healthy check guarantee the next request will work?

Warm-up: cancellation needs cooperation

Open the deadline source. The caller waits two seconds; the worker sleeps for three and ignores cancellation. If the process stayed alive afterward, its unbuffered send would have no receiver. Make the worker observe cancellation and wait for its exit explicitly.

What is the difference between stopping the wait and stopping the work?

How to run the exercises

Keep port 8080 for this website. The chat and shutdown exercises use 8080 by default. In your exercise copy, change the server port to an unused one such as 9080. Update the chat client's URL to match. Run the chat and shutdown experiments separately if they share that new port.

Open a terminal in /Users/carlisiacampos/code/src/github.com/learning/networking-with-go. For the standard-library exercises, run the relevant directory:

GO111MODULE=off go run ./exercises/part2/10-http-server-context

With that server running on 8083, a second terminal can demonstrate a client timeout:

curl --max-time 1 http://127.0.0.1:8083/

The Gorilla chat examples have their own modules. Change into the server directory and run go run .. Start each client in a separate terminal from its own directory with the same command.

cd exercises/part2/13-chat-server-gorilla
go run .

Use the reader's Notes button to record the behavior you observed and the tradeoff you would defend.

Read the examples critically