func (f StartTaskFunc) StartTask(conf *TaskConfig) {
	f(conf)
}
StartTask implements the TaskStarter interface.
package component
import (
	"context"
	"fmt"
	"os"
	"runtime/debug"
	"time"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
	"go.thethings.network/lorawan-stack/v3/pkg/log"
	"go.thethings.network/lorawan-stack/v3/pkg/random"
)
type TaskFunc func(context.Context) error
func (f TaskFunc) Execute(ctx context.Context, logger log.Interface) (err error) {
	defer func() {
		if p := recover(); p != nil {
			fmt.Fprintln(os.Stderr, p)
			os.Stderr.Write(debug.Stack())
			if pErr, ok := p.(error); ok {
				err = errTaskRecovered.WithCause(pErr)
			} else {
				err = errTaskRecovered.WithAttributes("panic", p)
			}
			logger.WithError(err).Error("Task panicked")
		}
	}()
	return f(ctx)
}
type TaskRestart uint8
const (
	TaskRestartNever TaskRestart = iota
	TaskRestartAlways
	TaskRestartOnFailure
)
type TaskBackoffIntervalFunc func(ctx context.Context, executionDuration time.Duration, invocation uint, err error) time.Duration
type TaskBackoffConfig struct {
	Jitter       float64
	IntervalFunc TaskBackoffIntervalFunc
}
func MakeTaskBackoffIntervalFunc(onFailure bool, resetDuration time.Duration, intervals ...time.Duration) TaskBackoffIntervalFunc {
	return func(ctx context.Context, executionDuration time.Duration, invocation uint, err error) time.Duration {
		switch {
		case onFailure && err == nil:
			return 0
		case executionDuration > resetDuration:
			return intervals[0]
		case invocation >= uint(len(intervals)):
			return intervals[len(intervals)-1]
		default:
			return intervals[invocation-1]
		}
	}
}
const (
	DefaultTaskBackoffResetDuration = time.Minute
	DefaultTaskBackoffJitter        = 0.1
)
var (
	DefaultTaskBackoffIntervals = [...]time.Duration{
		10 * time.Millisecond,
		50 * time.Millisecond,
		100 * time.Millisecond,
		time.Second,
	}
	DefaultTaskBackoffIntervalFunc = MakeTaskBackoffIntervalFunc(false, DefaultTaskBackoffResetDuration, DefaultTaskBackoffIntervals[:]...)
	DefaultTaskBackoffConfig = &TaskBackoffConfig{
		Jitter:       DefaultTaskBackoffJitter,
		IntervalFunc: DefaultTaskBackoffIntervalFunc,
	}
	DialTaskBackoffIntervals = [...]time.Duration{
		100 * time.Millisecond,
		time.Second,
		10 * time.Second,
	}
	DialTaskBackoffIntervalFunc = MakeTaskBackoffIntervalFunc(false, DefaultTaskBackoffResetDuration, DialTaskBackoffIntervals[:]...)
	DialTaskBackoffConfig = &TaskBackoffConfig{
		Jitter:       DefaultTaskBackoffJitter,
		IntervalFunc: DialTaskBackoffIntervalFunc,
	}
)
type TaskConfig struct {
	Context context.Context
	ID      string
	Func    TaskFunc
	Done    func()
	Restart TaskRestart
	Backoff *TaskBackoffConfig
}
func (c *Component) RegisterTask(conf *TaskConfig) {
	c.taskConfigs = append(c.taskConfigs, conf)
}
type TaskStarter interface {
	StartTask(*TaskConfig)
}
type StartTaskFunc func(*TaskConfig)