You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> A lightweight, type-safe, and retryable concurrent worker pool for Go — built on **`sync.WaitGroup`**, **semaphores**, **context**, and **condition variables**, _not_`errgroup`.
10
+
> A lightweight, type-safe, and retryable concurrent worker pool for Go — built on **`sync.WaitGroup`**, **semaphores**, **context**, and **atomic operations**, _not_`errgroup`.
11
11
12
12
`go-pool` provides deterministic, leak-free concurrency with automatic retries, result draining, and type-safe tasks, suitable for high-throughput Go applications.
13
13
14
14
---
15
15
16
16
## Features
17
17
18
-
- Type-safe generic workers (`Task[T]`)
19
-
-Graceful error propagation
20
-
-Built-in retry with exponential backoff + jitter
21
-
- Concurrent result draining (`Drain`)
18
+
- Type-safe generic drainer (`Drainer[T]`)
19
+
-Plain `Task` functions (`func() error`) for simplicity
20
+
-Optional retry with exponential backoff + jitter
21
+
- Concurrent result draining
22
22
- Deterministic shutdown (no goroutine leaks)
23
-
-Mutex + condition variable–protected data aggregation
-`GoPool` and `GoPoolWithDrainer` show consistent sub-microsecond operation times.
177
-
- Memory allocations remain extremely low — under 250 B/op even with drainer support.
178
-
- The performance delta vs `errgroup` reflects controlled synchronization overhead (mutex + condition variable).
179
-
- In practice, `go-pool` scales linearly with worker count and maintains predictable latency under load.
189
+

190
+
191
+
---
192
+
193
+
Even though `GoPool` adds a small constant overhead compared to `ErrGroup (≈8.5 ns per operation, 192 ns vs 183.5 ns)`,
194
+
it provides type safety, retries, deterministic cleanup, and concurrent draining — while staying well within ~1.05× of native concurrency performance.
195
+
196
+
Memory-wise, `GoPool` uses slightly more: `32 B/op` vs `24 B/op` and `1 vs 1 allocs/op`, negligible for most workloads considering the added features.
180
197
181
198
---
182
199
183
200
## Design Highlights
184
201
185
202
- Structured concurrency with `sync.WaitGroup`
186
203
- Controlled parallelism via semaphores
187
-
- Mutex + `sync.Cond`–protected drains
188
204
- Context-based cancellation and cleanup
189
205
- Exponential backoff retries
190
206
- Leak-free, deterministic shutdown
207
+
- Drainer supports unbuffered channels for high-volume inputs
191
208
192
209
---
193
210
194
-
## ⚠️ Notes and Best Practices
195
-
196
-
### General
211
+
## Notes and Best Practices
197
212
198
-
- Thread Safety — never access internal slices or channels directly.
199
-
- Non-blocking design — use `Drain()` or wait for pool completion instead of manual `close()` calls.
213
+
- **Thread Safety:** Never access internal slices/channels directly.
214
+
- **Drainer:** Use `Send()` and `Drain()`, do not close manually if multiple producers exist.
215
+
- **Task Management:** Wrap work with `NewTask(func() error)` and optionally `.WithRetry()`.
200
216
201
-
### Drainer (Drain)
202
-
203
-
- Create via `gopool.NewDrainer[T]()`
204
-
- Use `Send()` to safely push results
205
-
- Collect values using `Drain()`
206
-
- Internally guarded by `sync.Mutex` and `sync.Cond`
207
-
208
-
### Task and Worker Management
209
-
210
-
- Wrap async functions with `gopool.NewTask()`
211
-
- Chain configuration fluently using `.WithRetry()` and `.DrainTo()`
212
-
- Provide inputs using `.WithInput()`
213
-
214
-
### Pool
215
-
216
-
- Use `gopool.NewPool()` for controlled concurrency
217
-
- Limit parallelism with `.WithLimit(limit)`
218
-
- Apply retry policy globally with `.WithRetry(attempts, sleep)`
219
-
- Wait for all tasks to complete using `.Wait()`
217
+
---
220
218
221
-
###Testing
219
+
## Testing
222
220
223
-
- Run deterministic tests with:
224
221
```bash
225
222
go test -v ./...
226
-
```
227
-
- Benchmark performance with:
228
-
```bash
229
223
go test -bench . -benchmem -memprofile=mem.prof
230
224
```
231
-
---
232
-
233
-
## Summary
234
-
235
-
`go-pool` provides a modern, type-safe, and retryable abstraction over Go’s native synchronization primitives — combining simplicity, determinism, and high throughput.
0 commit comments