Skip to content

henrywhitaker3/flow

Folders and files

NameName
Last commit message
Last commit date
Feb 4, 2025
May 18, 2024
Jan 28, 2024
Jan 28, 2024
Jan 28, 2024
May 19, 2024
May 19, 2024
May 19, 2024
Feb 4, 2025
Feb 4, 2025
Jan 28, 2024
Jun 18, 2024
Aug 8, 2024
Jul 31, 2024
Apr 13, 2024
May 18, 2024
Aug 8, 2024
Aug 8, 2024
Jan 28, 2024
Jan 30, 2024
May 18, 2024
Jun 1, 2024
Jun 18, 2024
Jun 18, 2024

Repository files navigation

Flow

A collection of async/flow control functions

Usage

Eventually

Get the result of a function call later on:

res := flow.Eventually(context.Background(), func(ctx context.Context) (int, error) {
    return 5, nil
})

...

<-res.Done()
if res.Err() != nil {
    panic(res.Err())
}

fmt.Println(res.Out()) // prints 5

Groups

If you need to wait for multiple results to resolve:

fast := flow.Eventually(context.Background(), func(ctx context.Context) (int, error) {
    return 5, nil
})
slow := flow.Eventually(context.Background(), func(ctx context.Context) (string, error) {
    time.Sleep(time.Second * 5)
    return "bongo", nil
})

group := &flow.ResultGroup{}
group.Add(fast)
group.Add(slow)

// The wait function blocks until all results have resolved
group.Wait()

fmt.Println(fast.Out()) // prints 5
fmt.Println(slow.Out()) // prints bongo

Retry

To retry a function a 3 times:

i := 0
f := flow.Retry(func(ctx context.Context) (int, error) {
    defer func() { i++ }()
    if i < 2 {
        return 0, errors.New("demo error")
    }
    return 5, nil
}, 3)

// The above will call the function three times, and will return 5, nil on the third call
out, err := f(context.Background()) // err is nil
fmt.Println(out) // prints 5

To retyr a function 3 times with a millisecond delay between each try:

i := 0
f := flow.RetryDelay(func(ctx context.Context) (int, error) {
    defer func() { i++ }()
    if i < 2 {
        return 0, errors.New("demo error")
    }
    return 5, nil
}, 3, time.Millisecond)

out, err := f(context.Background()) // err is nil
fmt.Println(out) // prints 5

Throttle

To throttle a function call so that it runs once per second:

i := 1
f := flow.Throttle(func(ctx context.Context) (int, error) {
    defer func() { i++ }()
    return i, nil
}, time.Second)

for range 3 {
    fmt.Println(f(context.Background()))
}

Which will print:

1 <nil>
0 throttled
0 throttled

To throttle a function call so that it runs once per second, and returns the first value without a throttled error:

i := 1
f := flow.SilentThrottle(func(ctx context.Context) (int, error) {
    defer func() { i++ }()
    return i, nil
}, time.Millisecond)

for i := range 3 {
    if i == 2 {
        time.Sleep(time.Millisecond * 2)
    }
    fmt.Println(f(context.Background()))
    i++
}

Which will print:

1 <nil>
1 <nil>
2 <nil>