tezvyn:

Cancellation: Go context vs Rust sync stdlib

AI-drafted, machine-checkedSource: interviewadvanced
WHAT IT TESTS

cancellation propagation models.

OUTLINE

Go's context.Context threads a Done channel and deadline through call chains; Rust std has no built-in cancellation, so you wire an AtomicBool or channel and check it.

WHAT THIS TESTS Whether you understand cooperative cancellation, that Go bakes it into the standard library via context while Rust's synchronous std leaves it to you, and the limits of interrupting blocked operations.

A GOOD ANSWER COVERS Go's context.Context provides a Done channel that closes on cancel or deadline, an Err describing why, a Deadline, and Value for request-scoped data. You pass ctx as the first parameter through the call chain; handlers select on ctx.Done to bail out, and downstream calls inherit cancellation when you derive children with WithCancel, WithTimeout, or WithDeadline. For graceful shutdown you cancel the root context, and every goroutine observing Done returns. Rust's synchronous std has no context type. You construct your own cancellation signal, commonly an Arc<AtomicBool> set on shutdown, or a channel that workers check between units of work. The challenge is that this is cooperative: a thread already blocked inside a socket read will not notice the flag, so you must also arm a read timeout on the stream so the blocking call returns and the loop can re-check the signal.

COMMON WRONG ANSWERS Claiming Rust std offers context-like cancellation, or that setting an AtomicBool interrupts a blocked Read. Forgetting that Go's cancellation is also cooperative; ctx.Done only helps code that checks it.

LIKELY FOLLOW-UPS How does this improve under Tokio, where CancellationToken and select! plus future drop give true cancellation of in-flight async work? How do you propagate request IDs without context.Value, perhaps via explicit parameters or thread-locals? How do you drain in-flight requests during shutdown?

ONE CONCRETE EXAMPLE Go: ctx, cancel := context.WithCancel(parent); on SIGTERM call cancel(); the handler loop does select { case <-ctx.Done(): return; case work := <-jobs: ... }. Rust std: let stop = Arc::new(AtomicBool::new(false)); the handler loops while not stop.load, with the socket given a read timeout so it periodically wakes to check stop and exit cleanly.

Read the original → pkg.go.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.