Popularity
3.2
Growing
Activity
5.1
Declining
52
3
2

Programming language: Go
Tags: Goroutines    
Latest version: v1.1.1

breaker alternatives and similar packages

Based on the "Goroutines" category

Do you think we are missing an alternative of breaker or a related project?

Add another 'Goroutines' Package

README

🚧 breaker

Flexible mechanism to make execution flow interruptible.

Build Quality Documentation Coverage Awesome

💡 Idea

The breaker carries a cancellation signal to interrupt an action execution.

interrupter := breaker.Multiplex(
    breaker.BreakByContext(context.WithTimeout(req.Context(), time.Minute)),
    breaker.BreakByDeadline(NewYear),
    breaker.BreakBySignal(os.Interrupt),
)
defer interrupter.Close()

<-interrupter.Done() // wait context cancellation, timeout or interrupt signal

Full description of the idea is available here.

🏆 Motivation

I have to make github.com/kamilsk/retry package:

if err := retry.Retry(breaker.BreakByTimeout(time.Minute), action); err != nil {
    log.Fatal(err)
}

and github.com/kamilsk/semaphore package:

if err := semaphore.Acquire(breaker.BreakByTimeout(time.Minute), 5); err != nil {
    log.Fatal(err)
}

more consistent and reliable.

🤼‍♂️ How to

import (
    "bytes"
    "context"
    "fmt"
    "io"
    "net/http"
    "os"
    "time"

    "github.com/kamilsk/breaker"
)

var NewYear = time.Time{}.AddDate(time.Now().Year(), 0, 0)

func Handle(rw http.ResponseWriter, req *http.Request) {
    ctx, cancel := context.WithCancel(req.Context())
    defer cancel()

    deadline, _ := time.ParseDuration(req.Header.Get("X-Timeout"))
    interrupter := breaker.Multiplex(
        breaker.BreakByContext(context.WithTimeout(ctx, deadline)),
        breaker.BreakByDeadline(NewYear),
        breaker.BreakBySignal(os.Interrupt),
    )
    defer interrupter.Close()

    buf, work := bytes.NewBuffer(nil), Work(ctx, struct{}{})
    for {
        select {
        case b, ok := <-work:
            if !ok {
                rw.WriteHeader(http.StatusOK)
                io.Copy(rw, buf)
                return
            }
            buf.WriteByte(b)
        case <-interrupter.Done():
            rw.WriteHeader(http.StatusPartialContent)
            rw.Header().Set("Content-Range", fmt.Sprintf("bytes=0-%d", buf.Len()))
            io.Copy(rw, buf)
            return
        }
    }
}

func Work(ctx context.Context, _ struct{}) <-chan byte {
    outcome := make(chan byte, 1)

    go func() { ... }()

    return outcome
}

🧩 Integration

The library uses SemVer for versioning, and it is not BC-safe through major releases. You can use go modules or dep to manage its version.

$ go get -u github.com/kamilsk/breaker

$ dep ensure -add github.com/kamilsk/breaker

made with ❤️ for everyone