https://github.com/line/garr
Collection of high performance, thread-safe, lock-free go data structures
https://github.com/line/garr
golang high-performance library lock-free thread-safety
Last synced: 3 months ago
JSON representation
Collection of high performance, thread-safe, lock-free go data structures
- Host: GitHub
- URL: https://github.com/line/garr
- Owner: line
- License: apache-2.0
- Created: 2022-03-23T07:29:32.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-07-29T01:50:16.000Z (about 3 years ago)
- Last Synced: 2025-03-30T18:35:33.607Z (6 months ago)
- Topics: golang, high-performance, library, lock-free, thread-safety
- Language: Go
- Homepage:
- Size: 104 KB
- Stars: 371
- Watchers: 14
- Forks: 10
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Garr - Go libs in a Jar
[](https://pkg.go.dev/go.linecorp.com/garr)

[](https://goreportcard.com/report/go.linecorp.com/garr)Collection of high performance, thread-safe, lock-free go data structures.
* [adder](./adder/README.md) - Data structure to perform highly-performant sum under high contention. Inspired by [OpenJDK LongAdder](https://openjdk.java.net/)
* [circuit-breaker](./circuit-breaker/README.md) - Data structure to implement circuit breaker pattern to detect remote service failure/alive status.
* [queue](./queue/README.md) - Queue data structure, go implementation of `JDKLinkedQueue` and `MutexLinkedQueue` from `OpenJDK`.
* [retry](./retry/README.md) - Controls backoff between attempts in a retry operation.
* [worker-pool](./worker-pool/README.md) - Worker pool implementation in go to help perform multiple tasks concurrently with a fixed-but-expandable amount of workers.# Usage
## Getting started
```bash
go get -u go.linecorp.com/garr
```## Examples
Please find detailed examples in each sub-package.
### Adder
```go
package mainimport (
"fmt"
"time"ga "go.linecorp.com/garr/adder"
)func main() {
// or ga.DefaultAdder() which uses jdk long-adder as default
adder := ga.NewLongAdder(ga.JDKAdderType)for i := 0; i < 100; i++ {
go func() {
adder.Add(123)
}()
}time.Sleep(3 * time.Second)
// get total added value
fmt.Println(adder.Sum())
}
```#### Build your own Prometheus counter with Adder
```go
package promimport (
ga "go.linecorp.com/garr/adder""github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
)// NewCounterI64 creates a new CounterI64 based on the provided prometheus.CounterOpts.
func NewCounterI64(opts prometheus.CounterOpts) CounterI64 {
return CounterI64{counter: prometheus.NewCounter(opts)}
}// CounterI64 is optimized Prometheus Counter for int64 value type.
type CounterI64 struct {
val ga.JDKAdder
counter prometheus.Counter
}// Value returns current value.
func (c *CounterI64) Value() int64 {
return c.val.Sum()
}// Reset value.
func (c *CounterI64) Reset() {
c.val.Reset()
}// Desc returns metric desc.
func (c *CounterI64) Desc() *prometheus.Desc {
return c.counter.Desc()
}// Inc by 1.
func (c *CounterI64) Inc() {
c.val.Add(1)
}// Add by variant.
func (c *CounterI64) Add(val int64) {
if val > 0 {
c.val.Add(val)
}
}// Write implements prometheus.Metric interface.
func (c *CounterI64) Write(out *dto.Metric) (err error) {
if err = c.counter.Write(out); err == nil {
value := float64(c.val.Sum())
out.Counter.Value = &value
}
return
}// Collect implements prometheus.Collector interface.
func (c *CounterI64) Collect(ch chan<- prometheus.Metric) {
ch <- c
}// Describe implements prometheus.Collector interface.
func (c *CounterI64) Describe(ch chan<- *prometheus.Desc) {
ch <- c.counter.Desc()
}
```### Queue
```go
package mainimport (
"fmt""go.linecorp.com/garr/queue"
)func main() {
q := queue.DefaultQueue() // default using jdk linked queue// push
q.Offer(123)// return head queue but not remove
head := q.Peek()
fmt.Println(head)// remove and return head queue
polled := q.Poll()
fmt.Println(polled)
}
```### Circuit Breaker
```go
package mainimport (
cbreaker "go.linecorp.com/garr/circuit-breaker"
)func makeRequest() error {
return nil
}func main() {
cb := cbreaker.NewCircuitBreakerBuilder().
SetTicker(cbreaker.SystemTicker).
SetFailureRateThreshold(validFailureRateThreshold).
Build()if cb.CanRequest() {
err := makeRequest()
if err != nil {
cb.OnFailure()
} else {
cb.OnSuccess()
}
}
}
```