Skip to content

Commit 5a69e27

Browse files
authored
Merge pull request #9 from SangTran-127/docs/provide_better_readme
docs: Expand README with a detailed project description, installation
2 parents 5a8084a + ea654e4 commit 5a69e27

2 files changed

Lines changed: 51 additions & 8 deletions

File tree

README.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,52 @@
1-
# Quacker
1+
<p align="center">
2+
<img src="https://github.com/user-attachments/assets/7af9dc11-083c-4036-aae6-4f71331abe1d" width="400" alt="Quacker">
3+
</p>
24

3-
[![CI](https://github.com/SangTran-127/quacker/actions/workflows/ci.yml/badge.svg)](https://github.com/SangTran-127/quacker/actions)
4-
[![Go Reference](https://pkg.go.dev/badge/github.com/SangTran-127/quacker.svg)](https://pkg.go.dev/github.com/SangTran-127/quacker)
5-
[![Coverage](https://codecov.io/github/SangTran-127/quacker/graph/badge.svg?token=3YSWJQTMB7)](https://codecov.io/github/SangTran-127/quacker)
5+
<h1 align="center">Quacker</h1>
66

7+
<p align="center">
8+
<strong>Type-safe, composable, and observable concurrency patterns for Go</strong>
9+
</p>
710

8-
## License
9-
MIT
11+
<p align="center">
12+
<a href="https://github.com/SangTran-127/quacker/actions/workflows/ci.yml"><img src="https://github.com/SangTran-127/quacker/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
13+
<a href="https://pkg.go.dev/github.com/SangTran-127/quacker"><img src="https://pkg.go.dev/badge/github.com/SangTran-127/quacker.svg" alt="Go Reference"></a>
14+
<a href="https://codecov.io/github/SangTran-127/quacker"><img src="https://codecov.io/github/SangTran-127/quacker/graph/badge.svg?token=3YSWJQTMB7" alt="Coverage"></a>
15+
<a href="https://goreportcard.com/report/github.com/SangTran-127/quacker"><img src="https://goreportcard.com/badge/github.com/SangTran-127/quacker" alt="Go Report Card"></a>
16+
<img src="https://img.shields.io/badge/Made%20with-Go-1f425f.svg" alt="Made with Go">
17+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
18+
</p>
19+
20+
**Quacker** provides a suite of generic, high-performance concurrency primitives designed for modern Go applications. It simplifies complex concurrent workflows while ensuring type safety and observability.
21+
22+
## Installation
23+
24+
```bash
25+
go get github.com/SangTran-127/quacker
26+
```
27+
28+
**Requirements:** Go 1.25+
29+
30+
## Quick Guide
31+
32+
- Use [`fanout.FanOut`](https://pkg.go.dev/github.com/SangTran-127/quacker/fanout) to distribute work from a single stream to **multiple consumers**. Supports efficient `RoundRobin` load balancing or `Broadcast` messaging.
33+
- Use [`fanin.FanIn`](https://pkg.go.dev/github.com/SangTran-127/quacker/fanin) to **merge multiple channels** into a single cohesive stream.
34+
- Use [`workerpool.WorkerPool`](https://pkg.go.dev/github.com/SangTran-127/quacker/workerpool) for **bounded concurrency** when you need to process tasks with limited resources. Includes built-in task queuing, metrics tracking, and graceful shutdown.
35+
36+
## Highlights
37+
38+
- **Modern Go**: Leverages Go 1.25 features and strict type safety with generics.
39+
- **Observable**: First-class support for `Observer` interfaces (metrics, logging, tracing) and error/panic handlers.
40+
- **Robust**: Includes panic recovery, context cancellation propagation, and safe resource cleanup by default.
41+
- **Zero Dependencies**: Core logic depends only on the standard library (test deps excluded).
42+
43+
## Benchmarks
44+
45+
> **Coming Soon**
46+
>
47+
> Benchmarks against standard library implementations are currently being developed. Preliminary results show minimal overhead with significant usability gains.
48+
49+
---
50+
<p align="center">
51+
Built with ❤️ in <a href="https://go.dev/">Go</a> by <a href="https://github.com/SangTran-127">Sang Tran</a>
52+
</p>

fanin/fanin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ func (f *FanIn[T]) Run(ctx context.Context) <-chan T {
158158
// Don't store out(chan T) in FanIn struct
159159
// Follow these rules:
160160
// Whoever creates the channel is the one who closes it.
161-
// If store in struct, we can't Run(ctx) again because once it close
162-
// We cannot call it again
161+
// If stored in the struct, Run(ctx) cannot be invoked repeatedly because
162+
// once the channel is closed, it cannot be reopened or reused.
163163
out := make(chan T, f.cfg.BufferSize)
164164
f.done = make(chan struct{})
165165
f.mu.Unlock()

0 commit comments

Comments
 (0)