Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions templates/backend/concurrency.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Backend — Concurrency
[ID: backend-concurrency]

Universal rules for multi-threading, multi-processing, and async I/O.
Language-specific rules belong in the stack template via [EXTEND:
backend-concurrency].
Rules for multi-threading, multi-processing and async I/O; a stack
template extends this one with its language's rules.

## When to use what

Expand Down Expand Up @@ -39,24 +38,23 @@ CPU-bound work cannot be offloaded to a background job or worker process.

## Pitfalls

- **Deadlock**: two threads each waiting for a lock the other holds —
always acquire locks in a consistent order
- **Livelock**: threads repeatedly yielding to each other without making
progress — add backoff or a tiebreaker
- **Race condition**: outcome depends on scheduling order —
use a race detector during testing (e.g. `go test -race`, ThreadSanitizer)
- **Starvation**: low-priority work never gets scheduled —
bound queue sizes and use fair scheduling where possible
- **Thread-local state leakage**: in thread-pool or async contexts,
context (e.g. request ID, user identity) must be explicitly passed,
not stored in thread-locals
- Acquire locks in one consistent order, so no two threads deadlock
waiting on each other
- Add backoff or a tiebreaker where threads can livelock, yielding to each
other without progress
- Run a race detector in tests (e.g. `go test -race`, ThreadSanitizer) to
catch outcomes that depend on scheduling
- Bound queue sizes and schedule fairly where the runtime allows, so
low-priority work never starves
- Pass request context (request ID, user identity) explicitly in pools
and async code; never store it in thread-locals

## Observability

- Log the concurrency model in use at service startup (thread pool size,
event loop policy, worker count)
- Track thread/goroutine/task count as a metric — an unbounded growth
indicates a leak
- Track the thread, goroutine or task count as a metric; unbounded growth
is a leak
- Alert on deadlock symptoms: requests timing out uniformly across all
endpoints with no error in logs

Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/template-quality.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
templates/backend/api.md 94.9
templates/backend/auth.md 98.4
templates/backend/caching.md 100.0
templates/backend/concurrency.md 94.8
templates/backend/concurrency.md 98.1
templates/backend/database.md 100.0
templates/backend/edge.md 97.9
templates/backend/errors.md 98.3
Expand Down
Loading