liveBook · Manning

Timeout

As explained in Learn Go with Pocket-Sized Projects

A timeout is a configured limit on how long an operation may wait before it is interrupted or reported as failed.

A timeout limits how long an operation may wait before it is interrupted or reported as failed. Without one, an HTTP call can wait indefinitely when a server never answers. section 6.6.2

Apply timeouts deliberately:

  • Configure an http.Client with Timeout, such as 5*time.Second; the zero default means no timeout. section 6.6.2
  • Prefer an owned client over http.DefaultClient when application-wide mutation could produce conflicting behavior. section 6.6.2
  • Give each remote call its own context and deadline when a service performs multiple downstream calls. section 10.6 section 10.6.3
  • Cancel derived contexts with defer cancel(), and handle ctx.Done() so slow work returns context errors. section 10.6.3

Testing a slow database call

Wrap the repository call in context.WithTimeout(ctx, 100*time.Millisecond), then make a mock wait for two seconds or ctx.Done(). Expect context.DeadlineExceeded when the timeout wins. section 10.6.3

Listing 6.55 ecb.go: timeout example
// Client can call the bank to retrieve exchange rates.
type Client struct {
    client http.Client #1
}

// NewBank builds a Client that can fetch exchange rates
// within a given timeout.
func NewClient(timeout time.Duration) Client { #2
    return Client{
        client: http.Client{Timeout: timeout},
    }
}

// FetchExchangeRate fetches the ExchangeRate for the day and returns it.
func (c Client) FetchExchangeRate(
    source, target money.Currency) (money.ExchangeRate, error) {
    const path = 
        "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"

    resp, err := c.client.Get(path) #3
    [...]

Shows a reusable client constructor that accepts a time.Duration and configures an http.Client for exchange-rate requests. section 6.6.2

Listing 10.32 create_test.go: Testing the timeout
func TestCreate(t *testing.T) {
    // ...
    "db timeout": {
        db: func(ctl *minimock.Controller) *mocks.HabitCreatorMock {
            db := mocks.NewHabitCreatorMock(ctl)
            db.AddMock.Set(
                func(ctx context.Context, habit habit.Habit) error {
                    select {
                    // This tick is longer than a database call
                    case <-time.Tick(2 * time.Second):
                        return nil
                    case <-ctx.Done():
                        return ctx.Err()
                    }
                })
            return db
        },
        expectedErr: context.DeadlineExceeded, #1
    },

Shows a timeout test whose mock selects between a deliberately slow operation and the context's Done channel. section 10.6.3

How Learn Go with Pocket-Sized Projects covers it

How deep it goes
Explains client configuration, child contexts, cancellation, error detection, and tests, but defers broader timeout-value guidance.
Examples
Uses exchange-rate HTTP requests, a 100-millisecond repository timeout, slow mocks, and context deadline assertions.
What it assumes
Assumes familiarity with Go clients and errors while teaching timeout configuration and context cancellation through examples.
What you can do after
Builds bounded Go network and repository calls, then tests and classifies timeout failures.
How it connects
Connects HTTP clients, contexts, deadlines, cancellation, error handling, and mocking.

Also explained in

Compare how 9 books explain timeout →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Go with Pocket-Sized Projects. The section links point to the parts of the book it draws on.