Files
ocis/ocis-pkg/runner/types.go
2025-06-13 16:14:41 +02:00

94 lines
2.9 KiB
Go

package runner
import (
"fmt"
"os"
"strings"
"syscall"
"time"
)
var (
StopSignals = []os.Signal{syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT}
)
// Runable represent a task that can be executed by the Runner.
// It expected to be a long running task with an indefinite execution time,
// so it's suitable for servers or services.
// The task can eventually return an error, or nil if the execution finishes
// without errors
type Runable func() error
// Stopper represent a function that will stop the Runable.
// The stopper acts as a notification to the runable to know that the task
// needs to be finished now.
//
// The stopper won't need to crash the runable or force the runable to stop,
// instead, it will let the runable to know it has to stop and let it finish.
// This means that the runable might still run for a while.
//
// It's recommended the stopper to run asynchronously. This means that the
// stopper might need to spawn a goroutine. The intention is avoid blocking
// the running thread.
//
// Usually, the stoppers are the servers's `Shutdown()` or `Close()` methods,
// that will cause the server to start its shutdown procedure. As said, there
// is no need to force the shutdown, so graceful shutdowns are preferred if
// they're available
type Stopper func()
// Result represents the result of a runner.
// The result contains the provided runner's id (for easier identification
// in case of multiple results) and the runner's error, which is the result
// of the Runable function (might be nil if no error happened)
type Result struct {
RunnerID string
RunnerError error
}
// FormatError formats the error of the result.
// If the error is nil, it returns nil
func (r *Result) FormatError() error {
if r.RunnerError != nil {
return fmt.Errorf("runner %s failed: %w", r.RunnerID, r.RunnerError)
}
return nil
}
// TimeoutError is an error that should be used for timeouts.
// It implements the `error` interface
type TimeoutError struct {
RunnerID string
Duration time.Duration
}
// NewTimeoutError creates a new timeout error. Both runnerID and duration
// will be used in the error message
func NewTimeoutError(runnerID string, duration time.Duration) *TimeoutError {
return &TimeoutError{
RunnerID: runnerID,
Duration: duration,
}
}
// NewGroupTimeoutError creates a new timeout error. This is intended to be
// used for group runners when the timeout of the group is reached.
// The runner id will be set to "_unknown_" because we don't know which is
// the id of the missing runner.
func NewGroupTimeoutError(duration time.Duration) *TimeoutError {
return &TimeoutError{
RunnerID: "_unknown_",
Duration: duration,
}
}
// Error generates the message for this particular error.
func (te *TimeoutError) Error() string {
var sb strings.Builder
sb.WriteString("Runner ")
sb.WriteString(te.RunnerID)
sb.WriteString(" timed out after waiting for ")
sb.WriteString(te.Duration.String())
return sb.String()
}