Documentation
¶
Overview ¶
Package srvc provides simple but powerful Run functionality on top of Module abstraction. Ready made modules can be found under: github.com/go-srvc/mods.
Index ¶
- Constants
- Variables
- func Run(modules ...Module) error
- func RunAndExit(modules ...Module)
- type ErrGroup
- type ErrStr
- type Module
- func CtxMod(id string, runFn func(ctx context.Context) error) Module
- func IdleMod(id string, initFn, stopFn func() error) Module
- func InitMod(id string, initFn func() error) Module
- func Optional(enabled bool, m Module) Module
- func RunMod(id string, runFn func() error) Module
- func StopMod(id string, stopFn func() error) Module
Examples ¶
Constants ¶
const ErrModulePanic = ErrStr("module recovered from panic")
Variables ¶
var JoinErrors = errors.Join
JoinErrors is used by srvc to combine multiple errors into one. Override it to plug in custom multi-error formatting.
Functions ¶
func Run ¶
Run will run all given modules using following control flow:
- Exec Init() for each module in order. If any Init() returns error the Init loop is stopped and Stop() will be called for already initialized modules in reverse order.
- Exec Run() for each module in own goroutine so order isn't guaranteed.
- Wait for any Run() function to return nil or an error and move to Stop loop.
- Exec Stop() for modules in reverse order.
- Wait for all Run() goroutines to return.
- Return all errors or nil
Panics inside modules are recovered so other modules can shut down gracefully. Recovered panics are returned as errors wrapping ErrModulePanic.
Example ¶
package main
import (
"fmt"
"github.com/go-srvc/srvc"
)
type printMod struct{}
func (m *printMod) ID() string { return "printMod" }
func (m *printMod) Init() error { return nil }
func (m *printMod) Run() error { fmt.Println("hello"); return nil }
func (m *printMod) Stop() error { return nil }
func main() {
_ = srvc.Run(&printMod{})
}
Output:
func RunAndExit ¶
func RunAndExit(modules ...Module)
RunAndExit is convenience wrapper for Run that calls os.Exit with code 1 in case of an error. The common use case is to srvc.RunAndExit from main function and let the srvc handle the rest.
package main
import "github.com/go-srvc/srvc"
func main() {
srvc.RunAndExit(
// Add your modules here
)
}
Types ¶
type ErrGroup ¶
type ErrGroup struct {
// contains filtered or unexported fields
}
ErrGroup is a goroutine group that waits for all goroutines to finish and collects errors.
type Module ¶
type Module interface {
// ID should return identifier for logging purposes.
ID() string
// Init allows synchronous initialization of module.
Init() error
// Run should start the module and block until stop is called or error occurs.
Run() error
// Stop is called for synchronous cleanup and must cause Run to return.
// If Init ran, Stop is guaranteed to run as part of cleanup.
Stop() error
}
func CtxMod ¶ added in v1.10.0
CtxMod wraps runFn into a Module that calls runFn during the run phase with a context that is canceled when Stop is called. Init is a no-op and runFn must return once its context is done. Useful for run loops that already take a context.
func IdleMod ¶ added in v1.10.0
IdleMod wraps initFn and stopFn into a Module that has no work of its own during the run phase. Run blocks until the service shuts down and nil functions are no-ops. Useful for resources that are set up on init and torn down on stop.
func InitMod ¶ added in v1.9.0
InitMod wraps initFn into a Module that calls initFn during the init phase. Run blocks until the service shuts down and Stop is a no-op. Useful for one time setup that has no long running work of its own.
func Optional ¶ added in v1.11.0
Optional returns m when enabled is true. Otherwise m is skipped before the init phase, so none of its Init, Run or Stop functions are called. m is still constructed by the caller, so keep heavy work in Init. m may be nil when enabled is false.
Example ¶
package main
import (
"fmt"
"github.com/go-srvc/srvc"
)
type printMod struct{}
func (m *printMod) ID() string { return "printMod" }
func (m *printMod) Init() error { return nil }
func (m *printMod) Run() error { fmt.Println("hello"); return nil }
func (m *printMod) Stop() error { return nil }
func main() {
metricsEnabled := false
_ = srvc.Run(
&printMod{},
srvc.Optional(metricsEnabled, srvc.IdleMod("metrics", nil, nil)),
)
}
Output: