mirror of
https://github.com/MedUnes/go-kata.git
synced 2026-03-12 21:55:53 +07:00
43 lines
1.7 KiB
Markdown
43 lines
1.7 KiB
Markdown
# 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
|
||
You’re 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
|