Documentation ¶
Overview ¶
Package runutil provides helpers to advanced function scheduling control like repeat or retry.
It's very often the case when you need to excutes some code every fixed intervals or have it retried automatically. To make it reliably with proper timeout, you need to carefully arrange some boilerplate for this. Below function does it for you.
For repeat executes, use Repeat:
err := runutil.Repeat(10*time.Second, stopc, func() error { // ... })
Retry starts executing closure function f until no error is returned from f:
err := runutil.Retry(10*time.Second, stopc, func() error { // ... })
For logging an error on each f error, use RetryWithLog:
err := runutil.RetryWithLog(logger, 10*time.Second, stopc, func() error { // ... })
Another use case for runutil package is when you want to close a `Closer` interface. As we all know, we should close all implements of `Closer`, such as *os.File. Commonly we will use:
defer closer.Close()
The problem is that Close() usually can return important error e.g for os.File the actual file flush might happen (and fail) on `Close` method. It's important to *always* check error. Thanos provides utility functions to log every error like those, allowing to put them in convenient `defer`:
defer runutil.CloseWithLogOnErr(logger, closer, "log format message")
For capturing error, use CloseWithErrCapture:
var err error defer runutil.CloseWithErrCapture(&err, closer, "log format message") // ...
If Close() returns error, err will capture it and return by argument.
The rununtil.Exhaust* family of functions provide the same functionality but they take an io.ReadCloser and they exhaust the whole reader before closing them. They are useful when trying to use http keep-alive connections because for the same connection to be re-used the whole response body needs to be exhausted.
Index ¶
- func CloseWithErrCapture(err *error, closer io.Closer, format string, a ...interface{})
- func CloseWithLogOnErr(logger log.Logger, closer io.Closer, format string, a ...interface{})
- func DeleteAll(dir string, ignoreDirs ...string) error
- func ExhaustCloseWithErrCapture(err *error, r io.ReadCloser, format string, a ...interface{})
- func ExhaustCloseWithLogOnErr(logger log.Logger, r io.ReadCloser, format string, a ...interface{})
- func Repeat(interval time.Duration, stopc <-chan struct{}, f func() error) error
- func Retry(interval time.Duration, stopc <-chan struct{}, f func() error) error
- func RetryWithLog(logger log.Logger, interval time.Duration, stopc <-chan struct{}, ...) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseWithErrCapture ¶
CloseWithErrCapture runs function and on error return error by argument including the given error (usually from caller function).
func CloseWithLogOnErr ¶
CloseWithLogOnErr is making sure we log every error, even those from best effort tiny closers.
func DeleteAll ¶ added in v0.26.0
DeleteAll deletes all files and directories inside the given dir except for the ignoreDirs directories. NOTE: DeleteAll is not idempotent.
func ExhaustCloseWithErrCapture ¶ added in v0.26.0
func ExhaustCloseWithErrCapture(err *error, r io.ReadCloser, format string, a ...interface{})
ExhaustCloseWithErrCapture closes the io.ReadCloser with error capture but exhausts the reader before.
func ExhaustCloseWithLogOnErr ¶ added in v0.26.0
func ExhaustCloseWithLogOnErr(logger log.Logger, r io.ReadCloser, format string, a ...interface{})
ExhaustCloseWithLogOnErr closes the io.ReadCloser with a log message on error but exhausts the reader before.
func Repeat ¶
Repeat executes f every interval seconds until stopc is closed or f returns an error. It executes f once right after being called.
Example ¶
package main import ( "context" "fmt" "log" "time" "github.com/thanos-io/thanos/pkg/runutil" ) func main() { // It will stop Repeat 10 seconds later. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // It will print out "Repeat" every 5 seconds. err := runutil.Repeat(5*time.Second, ctx.Done(), func() error { fmt.Println("Repeat") return nil }) if err != nil { log.Fatal(err) } }
Output:
func Retry ¶
Retry executes f every interval seconds until timeout or no error is returned from f.
Example ¶
package main import ( "context" "fmt" "log" "time" "github.com/pkg/errors" "github.com/thanos-io/thanos/pkg/runutil" ) func main() { // It will stop Retry 10 seconds later. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // It will print out "Retry" every 5 seconds. err := runutil.Retry(5*time.Second, ctx.Done(), func() error { fmt.Println("Retry") return errors.New("Try to retry") }) if err != nil { log.Fatal(err) } }
Output:
Types ¶
This section is empty.