nettools/common/common.go

91 lines
1.6 KiB
Go
Raw Normal View History

2024-11-12 10:08:08 +00:00
package commonUtils
2024-11-12 08:10:09 +00:00
import (
"context"
"errors"
"fmt"
"sync"
"time"
)
func Retry(
ctx context.Context,
retryTimes int,
waitBeforeRetry time.Duration,
exec Task,
) (success bool, errs []error) {
var err error
errs = []error{}
for i := 0; i < retryTimes; i++ {
if err = exec(ctx); err == nil {
return true, errs
}
errs = append(errs, err)
}
return false, errs
}
func ExecTask(ctx context.Context, tasks Task) error {
errChan := make(chan error)
go func() {
errChan <- tasks(ctx)
}()
select {
case err := <-errChan:
return err
case <-ctx.Done():
return ctx.Err()
}
}
// ExecTasks Runs each task in a separate goroutine
// To set no task timeout -- set taskTimeout to 0
func ExecTasks(ctx context.Context, taskTimeout time.Duration, tasks []Task) error {
wg := &sync.WaitGroup{}
errChan := make(chan error)
wgChan := make(chan struct{})
wg.Add(len(tasks))
for i, task := range tasks {
go func() {
var cancel context.CancelFunc
taskCtx := context.Background()
if taskTimeout != 0 {
taskCtx, cancel = context.WithTimeout(taskCtx, taskTimeout)
}
if err := task(taskCtx); err != nil {
errChan <- errors.Join(fmt.Errorf("error running task %d: ", i), err)
}
wg.Done()
cancel()
}()
}
go func() {
wg.Wait()
close(wgChan)
}()
select {
case <-ctx.Done():
return ctx.Err()
case <-wgChan:
return nil
case err := <-errChan:
return err
}
}
func Ternar[T any](condition bool, ifTrue T, ifFalse T) T {
if condition {
return ifTrue
}
return ifFalse
}
func Must(err error) {
if err != nil {
panic(err.Error())
}
}