services

package module
Version: v0.0.0-...-11142f8 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2021 License: MIT Imports: 6 Imported by: 0

README

go Services

A package to manage background services in go applications.

Usage

Implement your service

A service is as simple as implementing the Runner interface:

type Runner interface {
    // Run is executed inside it's own go-routine and must not return until the service stops.
	// Run should only return after ctx.Done() or when a non recoverable error occurs.
	// Returning an error means the service did fail. On ctx.Done() the service should shutdown gracefully.
    Run(ctx context.Context) error
}

And register them inside a container:

	c := services.NewContainer() // or use services.Default()
	c.Register(s1)

There is also a builder pattern if you prefer not to implement the interface yourself:

	c := services.NewContainer()
	
	services.New("My Service").Run(func(ctx context.Context) error {
		// Implement your service here. Try to keep it running, only return fatal errors.
		<-ctx.Done()
		// Gracefully shut down your service here
		return nil
	}).Register(c)

Service names must be unique inside a single container.

Start and Stop your services

After registering all services you can start them all together.

	runCtx, runCtxCancel := context.WithCancel(context.Background())
	defer runCtxCancel()
	err := c.StartAll(runCtx)
	// err comes from the initialization (see below)

Stop all services, by either calling c.StopAll() or runCtxCancel(). All services also stop if any Run() function returns with or without an error.

You can actively wait for all services to stop:

	c.WaitAllStopped(context.Background())

    // You can check for any errors that might have caused the services to stop
	errs := c.ServiceErrors()

Service names

Services have names. Using the builder you just pass the name as string. Using a struct to implement Runner interface, the service name is derived from the struct name via reflection. To change this name you can implement the fmt.Stringer interface.

Service initialization

Before any Run() method gets called, optional Init() methods from the services.Initer interface are executed sequentially in oder of service registration.

// Initer can be optionally implemented for services that need to run initial startup code
// All init methods of registered services are executed sequentially
// When a starter returns an error, no further services are executed and the application shuts down
type Initer interface {
	Init(ctx context.Context) error
}

Or use the builder:

	services.New("My Service").
		Init(func(ctx context.Context) error {
			return nil
		}).
		Run(func(ctx context.Context) error {
			// Implement your service here. Try to keep it running, only return fatal errors.
			<-ctx.Done()
			// Gracefully shut down your service here
			return nil
		}).
		Register(c)

Documentation

Overview

Package services defines interfaces and methods to run background services in golang applications.

A Service is a somewhat independently running piece of code that runs in it's own go-routine it's initialized at some point and stopped later. Think of it as a deamon within the application.

All services are registered during init() or in main() and initialized all together by calling Container.StartAll() Services that implement the Initer interface, will run initial Init() code All services have to implement the Runner interface. Run() is blocking and only returns when the service stops working.

All services inside one container are started and stopped together. If one service fails, all are stopped.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

func New

func New(name string) *Builder

func (*Builder) Init

func (b *Builder) Init(f InitFunc) *Builder

func (*Builder) Register

func (b *Builder) Register(container *Container)

func (*Builder) RegisterDefault

func (b *Builder) RegisterDefault()

func (*Builder) Run

func (b *Builder) Run(f RunFunc) *Builder

type Container

type Container struct {
	// contains filtered or unexported fields
}

Container with all services The Container handles the following lifecycle: - Register all services - Start all services - Stop all services If a single service fails during init or run, all services inside the container are stopped.

func Default

func Default() *Container

func NewContainer

func NewContainer() *Container

func (*Container) Register

func (c *Container) Register(service Runner)

Register adds a service to the list of services to be initialized

func (*Container) ServiceErrors

func (c *Container) ServiceErrors() map[string]error

ServiceErrors returns all errors occured in services

func (*Container) StartAll

func (c *Container) StartAll(ctx context.Context) error

func (*Container) StopAll

func (c *Container) StopAll()

StopAll gracefully stops all services. If you need a timeout, passe a context with Timeout or Deadline

func (*Container) WaitAllStopped

func (c *Container) WaitAllStopped(ctx context.Context)

WaitAllStopped blocks until all services are stopped or context is exceeded

type FuncService

type FuncService func(ctx context.Context) error

FuncService is a wrapper that turns a func() into a service.Runner

func (FuncService) Run

func (f FuncService) Run(ctx context.Context) error

type InitFunc

type InitFunc func(ctx context.Context) error

type Initer

type Initer interface {
	Init(ctx context.Context) error
}

Initer can be optionally implemented for services that need to run initial startup code All init methods of registered services are executed sequentially When a starter returns an error, no further services are executed and the application shuts down

type RunFunc

type RunFunc func(ctx context.Context) error

type Runner

type Runner interface {
	// Run is executed inside it's own go-routine and must not return until the service stops.
	// Run should only return after ctx.Done() or when a non recoverable error occurs.
	// Returning an error means the service did fail. On ctx.Done() the service should shutdown gracefully.
	Run(ctx context.Context) error
}

type Waiter

type Waiter interface {
	Wait()
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL