// 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() } } }