https://github.com/samber/go-singleflightx
🧬 x/sync/singleflight but with generics, batching, sharding and nullable result
https://github.com/samber/go-singleflightx
cache channel concurrent deduplication generics go in-flight singleflight sync
Last synced: 10 months ago
JSON representation
🧬 x/sync/singleflight but with generics, batching, sharding and nullable result
- Host: GitHub
- URL: https://github.com/samber/go-singleflightx
- Owner: samber
- License: mit
- Created: 2024-03-04T20:03:22.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-09T18:03:33.000Z (over 1 year ago)
- Last Synced: 2024-11-09T19:17:46.594Z (over 1 year ago)
- Topics: cache, channel, concurrent, deduplication, generics, go, in-flight, singleflight, sync
- Language: Go
- Homepage: https://pkg.go.dev/github.com/samber/go-singleflightx
- Size: 53.7 KB
- Stars: 27
- Watchers: 2
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# go-singleflightx
[](https://github.com/samber/go-singleflightx/releases)

[](https://pkg.go.dev/github.com/samber/go-singleflightx)

[](https://goreportcard.com/report/github.com/samber/go-singleflightx)
[](https://codecov.io/gh/samber/go-singleflightx)
[](https://github.com/samber/go-singleflightx/graphs/contributors)
[](./LICENSE)
> x/sync/singleflight but better
## Features
This library is inspired by `x/sync/singleflight` but adds many features:
- 🧬 generics
- 🍱 batching: fetch multiple keys in a single callback, with in-flight deduplication
- 📭 nullable result
- 🍕 sharded groups
## 🚀 Install
```sh
go get github.com/samber/go-singleflightx
```
This library is v0 and follows SemVer strictly. No breaking changes will be made to exported APIs before v1.0.0.
## 💡 Doc
GoDoc: [https://pkg.go.dev/github.com/samber/go-singleflightx](https://pkg.go.dev/github.com/samber/go-singleflightx)
## Examples
Here is an example of a user retrieval in a caching layer:
```go
import "github.com/samber/go-singleflightx"
func getUsersByID(userIDs []string) (map[string]User, error) {
users := []User{}
// 📍 SQL query here...
err := sqlx.Select(&users, "SELECT * FROM users WHERE id IN (?);", userIDs...)
if err != nil {
return nil, err
}
var results = map[string]User{}
for _, u := range users {
results[u.ID] = u
}
return results, nil
}
func main() {
var g singleflightx.Group[string, User]
// 👇 concurrent queries will be dedup
output := g.DoX([]string{"user-1", "user-2"}, getUsersByID)
}
```
`output` is of type `map[K]singleflightx.Result[V]`, and will always have as many entries as requested, whatever the callback result.
```go
type Result[V any] struct {
Value singleflightx.NullValue[V] // 💡 A result is considered "null" if the callback did not return it.
Err error
Shared bool
}
type NullValue[V any] struct {
Value V
Valid bool
}
```
### Sharded groups, for high contention/concurrency environments
```go
g := singleflightx.NewShardedGroup[K string, User](10, func (key string) uint {
h := fnv.New64a()
h.Write([]byte(key))
return uint(h.Sum64())
})
// as usual, but if the keys match different shards, getUsersByID will be called twice
output := g.DoX([]string{"user-1", "user-2"}, getUsersByID)
```
### go-singleflightx + go-batchify
`go-batchify` groups concurrent tasks into a single batch. By adding `go-singleflightx`, you will be able to dedupe
```go
import (
"golang.org/x/sync/singleflight"
"github.com/samber/go-batchify"
)
var group singleflight.Group
batch := batchify.NewBatchWithTimer(
10,
func (ids []int) (map[int]string, error) {
return ..., nil
},
5*time.Millisecond,
)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
idStr := r.URL.Query().Get("id")
id, _ := strconv.Atoi(idStr)
value, err, _ = group.Do(idStr, func() (interface{}, error) {
return batch.Do(id)
})
// ...
})
```
## 🤝 Contributing
- Ping me on Twitter [@samuelberthe](https://twitter.com/samuelberthe) (DMs, mentions, whatever :))
- Fork the [project](https://github.com/samber/go-singleflightx)
- Fix [open issues](https://github.com/samber/go-singleflightx/issues) or request new features
Don't hesitate ;)
```bash
# Install some dev dependencies
make tools
# Run tests
make test
# or
make watch-test
```
## 👤 Contributors

## 💫 Show your support
Give a ⭐️ if this project helped you!
[](https://github.com/sponsors/samber)
## 📝 License
Copyright © 2023 [Samuel Berthe](https://github.com/samber).
This project is [MIT](./LICENSE) licensed.