192 Patterns from Effective Go Recipes (2024)

192 Patterns from Effective Go Recipes (2024)

This source emphasizes practical recipes across I/O, JSON streaming, HTTP middleware/timeouts, text normalization, function options, errors, concurrency, sockets, C interop, testing, and shipping.

What This Adds to Our Book

  • Recipe-level production patterns that are small, composable, and immediately reusable.
  • Better treatment of streaming and incremental processing.
  • Stronger shipping pipeline topics: build tags, static builds, version injection, Docker packaging.

Streaming-Oriented Mental Model

source -> decoder -> transform -> validator -> sink
          (stream)               (bounded memory)

Deep Integration Example: Streaming JSON Pipeline with Backpressure

package pipeline

import (
    "bufio"
    "context"
    "encoding/json"
    "errors"
    "io"
    "sync"
    "time"
)

type Event struct {
    ID   string `json:"id"`
    Type string `json:"type"`
}

func DecodeEvents(ctx context.Context, r io.Reader) (<-chan Event, <-chan error) {
    out := make(chan Event, 128)
    errCh := make(chan error, 1)

    go func() {
        defer close(out)
        defer close(errCh)

        dec := json.NewDecoder(bufio.NewReader(r))
        for {
            var e Event
            if err := dec.Decode(&e); err != nil {
                if errors.Is(err, io.EOF) {
                    return
                }
                errCh <- err
                return
            }

            select {
            case <-ctx.Done():
                errCh <- ctx.Err()
                return
            case out <- e:
            }
        }
    }()

    return out, errCh
}

func ProcessEvents(ctx context.Context, in <-chan Event, workers int, fn func(Event) error) error {
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    errCh := make(chan error, workers)
    var wg sync.WaitGroup

    for i := 0; i < workers; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for e := range in {
                opCtx, stop := context.WithTimeout(ctx, 250*time.Millisecond)
                err := fn(e)
                stop()
                if opCtx.Err() != nil {
                    errCh <- opCtx.Err()
                    cancel()
                    return
                }
                if err != nil {
                    errCh <- err
                    cancel()
                    return
                }
            }
        }()
    }

    wg.Wait()
    close(errCh)
    for err := range errCh {
        if err != nil {
            return err
        }
    }
    return nil
}

Why This Matters

Modern Go systems increasingly process streams instead of loading full datasets in memory. Recipe-style patterns are especially effective for this style because they focus on one robust tactic at a time.