life

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2019 License: MIT Imports: 14 Imported by: 25

README

Build Status codebeat badge Go Report Card Go doc Go Cover Go Walker

Life

Life is an application runtime life management framework for Go.

Install

go install github.com/redforks/life

Define packages

// in foo.go
func init() {
  life.Register("foo", startFoo, shutdownFoo, "bar") 
}

// in foobar.go
func init() {
  life.Register("foobar", startFooBar, nil, "foo", "bar")
}

// in bar.go
func init() {
  life.Register("bar", nil, shutdownBar)
}

A package has a name, optional onStart and onShutdown callbacks, zero or more depended packages. As above example, package foo depends on package bar', foobardepends bothfooandbar, while package bar` depends no one.

Packages can registered at any order, controlling init() execute order is nearlly impossible afterall. Life sort packages in dependence order (topological sorting): bar, foo, foobar, because bar depends on nothing, foobar depends on both.

It is common that initialize code depends on services provided by other packages, by using life, we can ensure they are run in correct order.

Packages have optional onStart callbacks, they will execute in depends order during life.Start(). OnShutdown callbacks execute in reverse order during life.Shutdown().

Hooks

If some code must execute at centern point, use hooks. Register hooks this way:

func init() {
    life.RegisterHook("foo", 10, life.BeforeRunning, fnFoo)
}

Hook names are used only in log.

Hooks are execute by order argument (2nd argument), lesser value execute first.

There are following hook types:

  • BeforeStarting, execute before all onStart callbacks.
  • BeforeRunning, execute before entering Running state, i.e. execute after all onStart callbacks.
  • BeforeShutingdown, execute before all onShutdown callbacks.
  • OnAbort, execute if life exit Unexpectedly.

States

Life manages application in states, here is the state diagram:

State diagram

In this diagram, round rectangles are states, rectangles are functions trigger the state changes, diamonds are callbacks and hooks registered to life package.

On application start, life state default to Initing', during this state, all packages init there codes by using init()` functions.

A typical main() function using life looks like:

func main() {
  life.Start()

  // run your service, such as:
  log.Print(http.ListenAndServe(":8080", nil))
  
  // Start shutdown process
  life.Shutdown()
}

life.Start() will:

  1. Execute BeforeStarting hooks
  2. Set state to Starting
  3. Execute OnStart callbacks in dependency order
  4. Execute BeforeStarting hooks
  5. Set state to Running

If panic cached in one of OnStart callbacks, life calls all started packages' OnShutdown callbacks to shutdown properly before application exit.

life.Shutdown() will:

  1. Execute BeforeShutingdown hooks
  2. Set state to Shutingdown
  3. Execute OnShutdown callbacks in reversed dependency order

Abort

Application may encounter fatal error must abort its execution, but some critical works must be done before abort. These work can use OnAbort hook.

OnAbort hooks called if a panic cached in one of OnStart and OnShutdown callbacks, but not called if life.Shutdown() succeed. OnAbort used in abnormal exit situation.

Call life.Abort() to trigger abort sequence on other abort situations, such as in a signal handler.

life.Abort() set application exit to 12, call life.Exit(n) if want other exit code.

Documentation

Overview

Package life manages life cycle of application. An application has follow life state:

  1. Config/init. If a package need initialization, provides Init() function. App main() function call these Init() functions in proper order. TODO: support united config framework, get config settings from config files and command arguments.

  2. Starting. App call life.Start() function indicate going to starting state. Each package register a function by life.OnStart(), they will called in register order.

  3. After life.Start() complete, going to running state.

  4. Stopping. Calling life.Shutdown() function going to shutdown state. Each package can register a function by life.OnShutdown(), they will called in reversed order.

    Use life package, app do not need to remember start every package in correct order. Keep calling of Start() inside the package itself, clean and elegant. Shutdown state enforces all package and go routines exit properly, without unpredictable state and corrupting data.

Index

Constants

View Source
const (
	// BeforeStarting hooks called before entering staring state
	BeforeStarting hookType = iota

	// BeforeRunning hooks called before entering running state
	BeforeRunning

	// BeforeShutingdown hooks called before entering shutingdown state
	BeforeShutingdown

	// OnAbort hooks called on abnormal error before exit. Abort hooks run in any state,
	// even before your package initialized, check your hooks to work on any states,
	// do not assume opened file, socket, channel, etc.
	OnAbort
)

Variables

This section is empty.

Functions

func Abort

func Abort()

Abort calling Abort hooks, and then exit. It is useful when fatal error occurred outside life package, ensure abort hooks done its job (such as: spork/errrpt, async log).

func EnsureState

func EnsureState(exp StateT, msg string)

EnsureState ensure current state is expected, panic with specific message if failed.

func EnsureStatef

func EnsureStatef(exp StateT, format string, a ...interface{})

EnsureStatef ensure current state is expected, panic with formatted message if failed.

func Exit

func Exit(n int)

Exit the problem with n as exit code after executing all OnAbort hooks. Like Abort() but can set exit code.

func Register

func Register(name string, onStart, onShutdown Callback, depends ...string)

Register a package, optionally includes depended packages. If not provides depended package, it will run as registered order. Depends need not to be exist, it will check and sort in Start().

func RegisterHook

func RegisterHook(name string, order int, typ hookType, fn HookFunc)

RegisterHook register a function that executed when typ hook event occurred. Name is used in log only. If multiple function hook to one hookType, they executed by order, smaller execute first, If two hooks have the same order, they will execute in any order.

func Shutdown

func Shutdown()

Shutdown put state to shutdown, Run all registered OnShutdown() function in reserved order.

func Start

func Start()

Start put state to starting, Run all registered OnStart() functions, if all succeed, move to running state. If any OnStart function panic, shutdown all started packages.

func WaitToEnd

func WaitToEnd()

WaitToEnd block calling goroutine until safely Shutdown. Can only be called in running and afterwards state.

Types

type Callback

type Callback func()

Callback is callback function called by life package.

type HookFunc

type HookFunc func()

HookFunc called when a hook event occurred. See hookType constants.

type StateT

type StateT int32

StateT indicate current application life state.

const (
	// Initing is the default state of life, in this state, all packages doing
	// init stuff using init() func.
	Initing StateT = iota

	// Starting state runs all package's start functions, they are running in
	// dependent order
	Starting

	// Running is the normal running state, after all packages started.
	Running

	// Shutingdown is the state to do the packages shutdown work.
	Shutingdown

	// Halt is a temporary state after all package shutdown and application not exit,
	// it is mainly used inside life package, normally outside package won't got a change
	// to saw Halt state.
	Halt
)

func State

func State() StateT

State return current life state.

func (StateT) String

func (i StateT) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL