services

package
v0.34.0-rc.0 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2024 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DescribeService

func DescribeService(service Service) string

DescribeService returns name of the service, if it has one, or returns string representation of the service.

func StartAndAwaitRunning

func StartAndAwaitRunning(ctx context.Context, service Service) error

StartAndAwaitRunning starts the service, and then waits until it reaches Running state. If service fails to start, its failure case is returned. Service must be in New state when this function is called.

Notice that context passed to the service for starting is the same as context used for waiting! If you need these contexts to be different, please use StartAsync and AwaitRunning directly.

func StopAndAwaitTerminated

func StopAndAwaitTerminated(ctx context.Context, service Service) error

StopAndAwaitTerminated asks service to stop, and then waits until service reaches Terminated or Failed state. If service ends in Terminated state, this function returns error. On Failed state, it returns the failure case. Other errors are possible too (eg. if context stops before service does).

Types

type BasicService

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

BasicService implements contract of Service interface, using three supplied functions: StartingFn, RunningFn and StoppingFn. When service is started, these three functions are called as service transitions to Starting, Running and Stopping state.

Since they are called sequentially, they don't need to synchronize access on the state. (In other words: StartingFn happens-before RunningFn, RunningFn happens-before StoppingFn).

All three functions are called at most once. If they are nil, they are not called and service transitions to the next state.

Context passed to StartingFn and RunningFn function is canceled when StopAsync() is called, or service enters Stopping state. This context can be used to start additional tasks from inside StartingFn or RunningFn. Same context is available via ServiceContext() method (not part of Service interface).

Possible orders of how functions are called:

* 1. StartingFn -- if StartingFn returns error, no other functions are called.

* 1. StartingFn, 2. StoppingFn -- StartingFn doesn't return error, but StopAsync is called while running StartingFn, or context is canceled from outside while StartingFn still runs.

* 1. StartingFn, 2. RunningFn, 3. StoppingFn -- this is most common, when StartingFn doesn't return error, service is not stopped and context isn't stopped externally while running StartingFn.

func NewBasicService

func NewBasicService(start StartingFn, run RunningFn, stop StoppingFn) *BasicService

NewBasicService returns service built from three functions (using BasicService).

func NewIdleService

func NewIdleService(up StartingFn, down StoppingFn) *BasicService

NewIdleService initializes basic service as an "idle" service -- it doesn't do anything in its Running state, but still supports all state transitions.

func NewTimerService

func NewTimerService(interval time.Duration, start StartingFn, iter OneIteration, stop StoppingFn) *BasicService

NewTimerService runs iteration function on every interval tick. When iteration returns error, service fails.

func (*BasicService) AddListener

func (b *BasicService) AddListener(listener Listener)

AddListener is part of Service interface.

func (*BasicService) AwaitRunning

func (b *BasicService) AwaitRunning(ctx context.Context) error

AwaitRunning is part of Service interface.

func (*BasicService) AwaitTerminated

func (b *BasicService) AwaitTerminated(ctx context.Context) error

AwaitTerminated is part of Service interface.

func (*BasicService) FailureCase

func (b *BasicService) FailureCase() error

FailureCase is part of Service interface.

func (*BasicService) ServiceContext

func (b *BasicService) ServiceContext() context.Context

ServiceContext returns context that this service uses internally for controlling its lifecycle. It is the same context that is passed to Starting and Running functions, and is based on context passed to the service via StartAsync.

Before service enters Starting state, there is no context. This context is stopped when service enters Stopping state.

This can be useful in code, that embeds BasicService and wants to provide additional methods to its clients.

Example:

func (s *exampleService) Send(msg string) bool {
	ctx := s.ServiceContext()
	if ctx == nil {
		// Service is not yet started
		return false
	}
	select {
	case s.ch <- msg:
		return true
	case <-ctx.Done():
		// Service is not running anymore.
		return false
	}
}

This is not part of Service interface, and clients of the Service should not use it.

func (*BasicService) ServiceName

func (b *BasicService) ServiceName() string

func (*BasicService) StartAsync

func (b *BasicService) StartAsync(parentContext context.Context) error

StartAsync is part of Service interface.

func (*BasicService) State

func (b *BasicService) State() State

State is part of Service interface.

func (*BasicService) StopAsync

func (b *BasicService) StopAsync()

StopAsync is part of Service interface.

func (*BasicService) WithName

func (b *BasicService) WithName(name string) *BasicService

WithName sets service name, if service is still in New state, and returns service to allow usage like NewBasicService(...).WithName("service name").

type Listener

type Listener interface {
	// Starting is called when the service transitions from NEW to STARTING.
	Starting()

	// Running is called when the service transitions from STARTING to RUNNING.
	Running()

	// Stopping is called when the service transitions to the STOPPING state.
	Stopping(from State)

	// Terminated is called when the service transitions to the TERMINATED state.
	Terminated(from State)

	// Failed is called when the service transitions to the FAILED state.
	Failed(from State, failure error)
}

Listener receives notifications about Service state changes.

func NewListener

func NewListener(starting, running func(), stopping, terminated func(from State), failed func(from State, failure error)) Listener

NewListener provides a simple way to build service listener from supplied functions. Functions are only called when not nil.

type NamedService

type NamedService interface {
	Service

	// ServiceName returns name of the service, if it has one.
	ServiceName() string
}

NamedService extends Service with a name.

type OneIteration

type OneIteration func(ctx context.Context) error

OneIteration is one iteration of the timer service. Called repeatedly until service is stopped, or this function returns error in which case, service will fail.

type RunningFn

type RunningFn func(serviceContext context.Context) error

RunningFn function is called when service enters Running state. When it returns, service will move to Stopping state. If RunningFn or Stopping return error, Service will end in Failed state, otherwise if both functions return without error, service will end in Terminated state.

type Service

type Service interface {
	// StartAsync starts Service asynchronously. Service must be in New State, otherwise error is returned.
	// Context is used as a parent context for service own context.
	StartAsync(ctx context.Context) error

	// AwaitRunning waits until service gets into Running state.
	// If service is in New or Starting state, this method is blocking.
	// If service is already in Running state, returns immediately with no error.
	// If service is in a state, from which it cannot get into Running state, error is returned immediately.
	AwaitRunning(ctx context.Context) error

	// StopAsync tell the service to stop. This method doesn't block and can be called multiple times.
	// If Service is New, it is Terminated without having been started nor stopped.
	// If Service is in Starting or Running state, this initiates shutdown and returns immediately.
	// If Service has already been stopped, this method returns immediately, without taking action.
	StopAsync()

	// AwaitTerminated waits for the service to reach Terminated or Failed state. If service is already in one of these states,
	// when method is called, method returns immediately.
	// If service enters Terminated state, this method returns nil.
	// If service enters Failed state, or context is finished before reaching Terminated or Failed, error is returned.
	AwaitTerminated(ctx context.Context) error

	// FailureCase returns error if Service is in Failed state.
	// If Service is not in Failed state, this method returns nil.
	FailureCase() error

	// State returns current state of the service.
	State() State

	// AddListener adds listener to this service. Listener will be notified on subsequent state transitions
	// of the service. Previous state transitions are not replayed, so it is suggested to add listeners before
	// service is started.
	//
	// AddListener guarantees execution ordering across calls to a given listener but not across calls to
	// multiple listeners. Specifically, a given listener will have its callbacks invoked in the same order
	// as the service enters those states. Additionally, at most one of the listener's callbacks will execute
	// at once. However, multiple listeners' callbacks may execute concurrently, and listeners may execute
	// in an order different from the one in which they were registered.
	AddListener(listener Listener)
}

Service defines interface for controlling a service.

State diagram for the service:

   ┌────────────────────────────────────────────────────────────────────┐
   │                                                                    │
   │                                                                    ▼
┌─────┐      ┌──────────┐      ┌─────────┐     ┌──────────┐      ┌────────────┐
│ New │─────▶│ Starting │─────▶│ Running │────▶│ Stopping │───┬─▶│ Terminated │
└─────┘      └──────────┘      └─────────┘     └──────────┘   │  └────────────┘
                   │                                          │
                   │                                          │
                   │                                          │   ┌────────┐
                   └──────────────────────────────────────────┴──▶│ Failed │
                                                                  └────────┘

type StartingFn

type StartingFn func(serviceContext context.Context) error

StartingFn is called when service enters Starting state. If StartingFn returns error, service goes into Failed state. If StartingFn returns without error, service transitions into Running state (unless context has been canceled).

serviceContext is a context that is finished at latest when service enters Stopping state, but can also be finished earlier when StopAsync is called on the service. This context is derived from context passed to StartAsync method.

type State

type State int

State of the service. See Service interface for full state diagram.

const (
	New        State = iota // New: Service is new, not running yet. Initial State.
	Starting                // Starting: Service is starting. If starting succeeds, service enters Running state.
	Running                 // Running: Service is fully running now. When service stops running, it enters Stopping state.
	Stopping                // Stopping: Service is shutting down
	Terminated              // Terminated: Service has stopped successfully. Terminal state.
	Failed                  // Failed: Service has failed in Starting, Running or Stopping state. Terminal state.
)

Possible states to represent the service State.

func (State) String

func (s State) String() string

type StoppingFn

type StoppingFn func(failureCase error) error

StoppingFn function is called when service enters Stopping state. When it returns, service moves to Terminated or Failed state, depending on whether there was any error returned from previous RunningFn (if it was called) and this StoppingFn function. If both return error, RunningFn's error will be saved as failure case for Failed state. Parameter is error from Running function, or nil if there was no error.

Jump to

Keyboard shortcuts

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