We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Timeouts

Requests that take too long hold connections open and consume server resources, making DoS attacks much more effective. Go's http.Server exposes separate timeouts for each phase of a connection:

server := &http.Server{
    Addr:              ":3030",
    Handler:           handler,
    ReadHeaderTimeout: 10 * time.Second,
    ReadTimeout:       30 * time.Second,
    WriteTimeout:      30 * time.Second,
    IdleTimeout:       120 * time.Second,
}

ReadHeaderTimeout and ReadTimeout stop slow clients from tying up a connection while sending a request. WriteTimeout bounds response writes, and IdleTimeout closes keep-alive connections that sit unused.

Server timeouts don't cancel a slow operation inside a handler. For that, derive a deadline from the request's context.Context and pass it into the work:

timeoutContext, cancel := context.WithTimeout(request.Context(), 2 * time.Second)
defer cancel()

reservation, err := reserve(timeoutContext, order)

If reserve is still running after two seconds, the deadline expires, timeoutContext.Done() closes, and timeoutContext.Err() returns context.DeadlineExceeded. Creating a deadline can't stop code that ignores it. The operation must receive from the context's Done channel and return the error.

These timeouts are useful for database queries, third-party API calls, and anything else that can hang indefinitely.

Assignment

Bearly Secure's simulated Acorn fulfillment reservation can stall checkout indefinitely.

Bound both incoming requests and the fulfillment call.

With Bearly Secure still running, run and submit the CLI tests from the project root.