Files
go-kata/02-performance-allocation/12-sync-pool-buffer-middleware/README.md
2026-01-04 20:53:07 +01:00

43 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kata 12: The sync.Pool Buffer Middleware
**Target Idioms:** `sync.Pool`, Avoiding GC Pressure, `bytes.Buffer` Reset, Benchmarks (`-benchmem`)
**Difficulty:** 🔴 Advanced
## 🧠 The "Why"
In Go, performance regressions often come from allocation/GC churn, not “slow CPU”.
People use `sync.Pool` incorrectly:
- pooling long-lived objects (wrong),
- forgetting to reset buffers (data leak),
- storing huge buffers back into the pool (memory bloat).
This kata is about **safe pooling** for high-throughput handlers.
## 🎯 The Scenario
Youre writing an HTTP middleware that:
- reads up to 16KB of request body for audit logging
- must not allocate per-request in the hot path
## 🛠 The Challenge
Implement a middleware:
- `func AuditBody(max int, next http.Handler) http.Handler`
### 1. Functional Requirements
- [ ] Read up to `max` bytes of request body (do not consume beyond `max`).
- [ ] Log the captured bytes with `slog` fields.
- [ ] Pass the request downstream intact (body still readable).
### 2. The "Idiomatic" Constraints (Pass/Fail Criteria)
- [ ] **Must** use `sync.Pool` to reuse buffers.
- [ ] **Must** `Reset()`/clear buffers before putting back.
- [ ] **Must** bound memory: never keep buffers larger than `max` in the pool.
- [ ] Provide a benchmark showing reduced allocations (`go test -bench . -benchmem`).
## 🧪 Self-Correction (Test Yourself)
- **If a request leaks previous request content:** you failed (no reset).
- **If allocations are ~O(requests):** you failed pooling.
- **If buffers grow unbounded and stay in pool:** you failed memory bounds.
## 📚 Resources
- https://pkg.go.dev/sync
- https://go.dev/doc/gc-guide
- https://go.dev/blog/pprof