Documentation
¶
Index ¶
- Constants
- Variables
- func InitiateShutdown() error
- func IsShuttingDown() bool
- func ListenToOSSignals(interceptSIGINT, interceptSIGTERM bool)
- func StopOSSignalListening()
- func WaitUntilAppShutdownInitiated()
- type IUnit
- type MultiUnitOperationConfig
- type UnitAvailability
- type UnitLifecycleRunner
- type UnitManager
- func (um *UnitManager) AddUnit(unit IUnit) error
- func (um *UnitManager) GetUnit(name string) (IUnit, error)
- func (um *UnitManager) ListUnitStates() (map[string]int32, error)
- func (um *UnitManager) Pause(unitName string, timeoutMillis ...int64) (UnitOperationResult, error)
- func (um *UnitManager) PauseScheme() (UnitManagerOperationResult, error)
- func (um *UnitManager) Quit(unitName string, timeoutMillis ...int64) (UnitOperationResult, error)
- func (um *UnitManager) QuitAll() (UnitManagerOperationResult, error)
- func (um *UnitManager) SetCustomPauseScheme(scheme []MultiUnitOperationConfig) error
- func (um *UnitManager) SetOperationScheme(scheme []MultiUnitOperationConfig) error
- func (um *UnitManager) Start(unitName string, timeoutMillis ...int64) (UnitOperationResult, error)
- func (um *UnitManager) StartScheme() (UnitManagerOperationResult, error)
- func (um *UnitManager) WaitUntilComplete() UnitManagerOperationResult
- type UnitManagerOperationResult
- type UnitOperationResult
Constants ¶
const ( STNotInitialized int32 = iota STInitializing STPaused STStarting STStarted STPausing STQuitting STQuit )
UnitLifecycleRunner states
const NegativeOpId int64 = -1
NegativeOpId identifies an operation that doesn't exist or haven't started due to error.
Variables ¶
var ( DefaultUnitStartPeriodMillis int64 = 5000 DefaultUnitPausePeriodMillis int64 = 5000 DefaultUnitQuitPeriodMillis int64 = 5000 DefaultUnitLifecycleChannelBufferSize = 1 )
var ( ErrUnitAlreadyExists = errors.New("unit already exists") ErrUnitHasUnexpectedState = errors.New("unit has unexpected state") ErrUnitNotFound = errors.New("unit not found") ErrStartupSchemeNotDefined = errors.New("startup scheme not defined") ErrShutdownSchemeNotDefined = errors.New("shutdown scheme not defined") ErrOperationFailed = errors.New("operation failed") ErrBusy = errors.New("busy (previous operation not complete)") ErrSkippedByUnitManager = errors.New("skipped by UnitManager") ErrTimedOut = errors.New("timed out") ErrShuttingDown = errors.New("already shutting down") // ErrOperationIdMismatch means that WaitUntilComplete method // has been waiting for wrong operation. This may be a sign of a race condition // when you call UnitManager methods from different goroutines without // proper synchronization. ErrOperationIdMismatch = errors.New("operation ID mismatch") )
Errors
var ( UmcoIdle = "idle" UmcoInit = "init" UmcoStart = "start" UmcoPause = "pause" UmcoQuit = "quit" UmcoGetInfo = "get_info" UmcoModifyScheme = "modify_scheme" )
UnitManagerCurrentOperation string IDs
var GlobalShutdownChan = make(chan struct{})
GlobalShutdownChan signals the application shutdown after it is closed by the InitiateShutdown function. You can wait for the closure of this channel from any goroutine. Do NOT close it manually with 'close' function, use app.InitiateShutdown instead.
var M = NewUnitManager()
M is a global UnitManager for your app that is created automatically. In most cases you don't have to create your own UnitManagers.
Functions ¶
func InitiateShutdown ¶
func InitiateShutdown() error
InitiateShutdown initiates the global application shutdown. This function doesn't block, it is thread-safe and can be called from any goroutine.
Returns: nil if it succeeds or error otherwise.
func IsShuttingDown ¶
func IsShuttingDown() bool
IsShuttingDown returns true if the app is currently shutting down. It can be used e.g. by a goroutine to plan incoming request processing strategy, even though better option would be to use unit's shutdown mechanism. Also consider using GlobalShutdownChan in the 'select' statements instead of this function.
This function doesn't block, it is thread-safe and can be called from any goroutine.
func ListenToOSSignals ¶
func ListenToOSSignals(interceptSIGINT, interceptSIGTERM bool)
ListenToOSSignals enables app to intercept OS signals SIGINT and/or SIGTERM to initiate graceful shutdown (SIGKILL can't be intercepted by a user application and thus is not listed as a parameter).
This function doesn't block and is thread-safe. Use StopOSSignalListening to revert the effect of calling this function if required.
Example:
func main() { fmt.Println("== app started ==") // Start app tasks here in separate goroutines... app.ListenToOSSignals(true, true) app.WaitUntilAppShutdownInitiated() // blocks until Ctrl+C pressed // Do graceful shutdown here... fmt.Println("== app exited ==") }
func StopOSSignalListening ¶
func StopOSSignalListening()
StopOSSignalListening cancels the effect of previously called ListenToOSSignals and disconnects system signals from global app shutdown mechanism.
This function doesn't block and is thread-safe. It is allowed to call ListenToOSSignals again after calling this function.
func WaitUntilAppShutdownInitiated ¶
func WaitUntilAppShutdownInitiated()
WaitUntilAppShutdownInitiated blocks until global app shutdown is initiated.
This function is thread-safe and can be called from any goroutine.
Types ¶
type IUnit ¶
type IUnit interface { UnitRunner() *UnitLifecycleRunner UnitStart() UnitOperationResult UnitPause() UnitOperationResult UnitQuit() UnitOperationResult UnitAvailability() UnitAvailability }
IUnit defines an interface to be implemented by a custom Unit.
type MultiUnitOperationConfig ¶
type MultiUnitOperationConfig struct { // UnitNames lists units on which the operation is to be performed. UnitNames []string // StartTimeoutMillis defines the timeout in milliseconds // for the start operation for the whole unit set // (and each unit as well because within one set they start in parallel). // If this value is zero, the DefaultUnitStartPeriodMillis is used. StartTimeoutMillis int64 // PauseTimeoutMillis defines the timeout in milliseconds // for the pause operation for the whole unit set // (and each unit as well because within one set they pause in parallel). // If this value is zero, the DefaultUnitPausePeriodMillis is used. PauseTimeoutMillis int64 // QuitTimeoutMillis defines the timeout in milliseconds // for the quit operation for the whole unit set // (and each unit as well because within one set they quit in parallel). // If this value is zero, the DefaultUnitQuitPeriodMillis is used. QuitTimeoutMillis int64 }
MultiUnitOperationConfig defines the configuration of a single operation on a set of units. Used by UnitManager startup and shutdown schemes.
type UnitAvailability ¶
type UnitAvailability int32
UnitAvailability describes availability of the unit's API.
const ( // Unit's API is permanently not available. UNotAvailable UnitAvailability = iota UTemporarilyUnavailable // Only part of Unit's API available. UPartiallyAvailable // Unit's API available. UAvailable )
type UnitLifecycleRunner ¶
type UnitLifecycleRunner struct {
// contains filtered or unexported fields
}
UnitLifecycleRunner runs the lifecycle message loop for each Unit.
func NewUnitLifecycleRunner ¶
func NewUnitLifecycleRunner(name string) *UnitLifecycleRunner
func (*UnitLifecycleRunner) Name ¶
func (r *UnitLifecycleRunner) Name() string
Name returns Unit's name.
func (*UnitLifecycleRunner) SetOwner ¶
func (r *UnitLifecycleRunner) SetOwner(owner IUnit)
func (*UnitLifecycleRunner) State ¶
func (r *UnitLifecycleRunner) State() int32
State returns current state of the unit. It is not guaranteed that the state won't change in the nearest future.
type UnitManager ¶
type UnitManager struct {
// contains filtered or unexported fields
}
func NewUnitManager ¶
func NewUnitManager() *UnitManager
func (*UnitManager) AddUnit ¶
func (um *UnitManager) AddUnit(unit IUnit) error
AddUnit is thread-safe.
func (*UnitManager) GetUnit ¶
func (um *UnitManager) GetUnit(name string) (IUnit, error)
GetUnit returns a reference to the Unit with the specified name. The reference is guaranteed to remain valid as long as the UnitManager itself is valid because, once the Unit is added to the UnitManager, it can't be removed.
func (*UnitManager) ListUnitStates ¶
func (um *UnitManager) ListUnitStates() (map[string]int32, error)
ListUnitStates lists all units previously added to UnitManager and their current states.
func (*UnitManager) Pause ¶
func (um *UnitManager) Pause(unitName string, timeoutMillis ...int64) ( UnitOperationResult, error)
Pause pauses the unit and blocks until complete. Output parameters:
UnitOperationResult - unit internal error if any; error - UnitManager error.
func (*UnitManager) PauseScheme ¶
func (um *UnitManager) PauseScheme() (UnitManagerOperationResult, error)
PauseScheme pauses scheme synchronously and blocks until it is complete.
func (*UnitManager) Quit ¶
func (um *UnitManager) Quit(unitName string, timeoutMillis ...int64) ( UnitOperationResult, error)
Quit quits the unit and blocks until complete. Output parameters:
UnitOperationResult - unit internal error if any; error - UnitManager error.
func (*UnitManager) QuitAll ¶
func (um *UnitManager) QuitAll() (UnitManagerOperationResult, error)
QuitAll quits all units of the UnitManager and blocks until it is complete.
func (*UnitManager) SetCustomPauseScheme ¶
func (um *UnitManager) SetCustomPauseScheme(scheme []MultiUnitOperationConfig) error
SetCustomPauseScheme sets the shutdown scheme for UnitManager. If not set, the shutdown order will be reverse to startup order.
func (*UnitManager) SetOperationScheme ¶
func (um *UnitManager) SetOperationScheme(scheme []MultiUnitOperationConfig) error
SetOperationScheme sets the operation scheme that defines both unit start and pause orders and respective timeouts. The pause order will be the reverse of the start order. If there is a need of a custom pause order, use SetCustomPauseScheme method in addition to this.
func (*UnitManager) Start ¶
func (um *UnitManager) Start(unitName string, timeoutMillis ...int64) ( UnitOperationResult, error)
Start starts the unit and blocks until complete. Output parameters:
UnitOperationResult - unit internal error if any; error - UnitManager error.
func (*UnitManager) StartScheme ¶
func (um *UnitManager) StartScheme() (UnitManagerOperationResult, error)
StartScheme starts scheme synchronously and blocks until it is complete.
func (*UnitManager) WaitUntilComplete ¶
func (um *UnitManager) WaitUntilComplete() UnitManagerOperationResult
WaitUntilComplete blocks until current operation completes and returns the result. It is thread-safe, multiple goroutines can wait simultaneously.
type UnitManagerOperationResult ¶
type UnitManagerOperationResult struct { OpName string // OpId uniquely identifies the operation. OpId int64 // OK is true if all units completed the operation successfully. OK bool // CollateralErrors is true if at least one unit encountered // a collateral error during operation. CollateralErrors bool ResultMap map[string]UnitOperationResult }