55 lines
1.2 KiB
Go
55 lines
1.2 KiB
Go
// Package toolkit contains useful utilities which are not specific to any
|
|
// specific part of isle.
|
|
package toolkit
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"time"
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
|
)
|
|
|
|
// IsZero returns true if the value is equal to its zero value according to
|
|
// reflect.DeepEqual.
|
|
func IsZero[T any](v T) bool {
|
|
var zero T
|
|
return reflect.DeepEqual(v, zero)
|
|
}
|
|
|
|
// Ptr returns a pointer to the given value.
|
|
func Ptr[T any](v T) *T {
|
|
return &v
|
|
}
|
|
|
|
// UntilTrue will repeatedly call the given callback, waiting the given duration
|
|
// between calls until:
|
|
// - The context is canceled, returning the context's error
|
|
// - The callback returns an error, returning that error
|
|
// - The callback returns true, returning nil
|
|
func UntilTrue(
|
|
ctx context.Context,
|
|
logger *mlog.Logger,
|
|
period time.Duration,
|
|
fn func() (bool, error),
|
|
) error {
|
|
ctx = mctx.Annotate(ctx, "retryAfter", period)
|
|
|
|
for {
|
|
if ok, err := fn(); err != nil {
|
|
return err
|
|
} else if ok {
|
|
return nil
|
|
}
|
|
|
|
logger.Info(ctx, "Waiting before retrying")
|
|
|
|
select {
|
|
case <-time.After(period):
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
}
|
|
}
|
|
}
|