lifecycle

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2023 License: MIT Imports: 0 Imported by: 0

README

Simple and flexible Go lifecycle manager library.

It helps to confiigure and run multiple services within one application. It has components to manage application lifecycle, handle system signals to implement graceful shutdown, service state monitoring tools, health-check built-in service, and adapters for common scenarios (e.g. http server).

In some aspects it's similar to github.com/uber-go/fx library but there are main differences:

  • it's not DI (dependency injection) containers, only lifecycle manager.
  • no reflection and magic inside, just static types.
  • flexible configuration for lifecycle manager and for each service if needed.
  • built-in healthcheck service monitoring tools.

You can check /examples dir to see working code.

See godoc: GoDoc

Install

Install using go get:

go get github.com/g4s8/go-lifecycle@latest

Usage

Register startup and shutdown hooks:

In this example:

  • lifecycle.New - creates new lifecycle manager.
  • RegisterStartupHook - registers func as startup hook and calls it during startup phase.
  • RegisterShutdownHook - registers func as shutdown hook and calls it on shutdown.
  • lf.Start - starts all services and call startup hooks.
lf := lifecycle.New(lifecycle.DefaultConfig)
lf.RegisterStartupHook("my-service", func(ctx context.Context, errCh chan<- error) error {
        fmt.Println("My service started")
        return nil
})
lf.RegisterShutdownHook("cleanup-hook", func(ctx context.Context) error {
        return os.Remove("/tmp/cache-file")
})
lf.Start()

Shutdown on SIGTERM:

sig := lifecycle.NewSignalHandler(lf, nil)
sig.Start(lifecycle.DefaultShutdownConfig)

The lifecycle will shut down, on SIGTERM or interrup signals.

Configure lifecycle behavior

lf := lifecycle.New(lifecycle.Config{
        StartupTimeout: 3*time.Second, // 3 seconds timout for startup, otherwise fail
        ShutdownTimeout: 4*time.Second, // 4 seconds timeout for shutdown, otherwise fail
        StartStrategy: StartStrategyFailFast | StartStrategyRollbackOnError
})

There are 3 startup strategies for lifecycle manager:

  • StartStrategyFailFast - lifecycle manager will fail on Start if any service fails.
  • StartStrategyStartAll - lifecycle manager will continue on Start if one or many services fails.
  • StartStrategyRollbackOnError - lifecycle manager will stop all started services in case of start error.

Report service errors

The channnel errCh should be used to report service errors, depens on configuration the server could be restarted:

lf.RegisterStartupHook("web-service", func(ctx context.Context, errCh chan<- error) error {
	ln, err := net.Listen("tcp", ":80")
	if err != nil {
		return fmt.Errorf("listen tcp: %w", err)
	}
	go func() {
		if err := srv.Serve(ln); err != nil {
			if err != http.ErrServerClosed {
				errCh <- errors.Wrap(err, "serve")
				return
			}
		}
	}()
	return nil
})

Configure service

lf.RegisterService(types.ServiceConfig{
        Name:         "my-service",
        StartupHook:  service.Start,
        ShutdownHook: service.Stop,
        RestartPolicy: types.ServiceRestartPolicy{
                RestartOnFailure: true,
                RestartCount:     3,
                RestartDelay:     time.Millisecond * 200,
        },
})

Here:

  • Name is a name of the service
  • StartupHook - method to call on startup
  • ShutdownHook - method to call on shutdown
  • RestartPolicy - service restart rules:
  • RestartOnFailure - restart service in case of runtime errors reported to errCh.
  • RestartCount - number of restart attemts until lifecycle manager gives up.
  • RestartDelay - min time interval between restart attempts.

Run HTTP web service

The package github.com/g4s8/go-lifecycle/pkg/adaptors contains adaptors for common services, e.g. web server:

web := http.NewServeMux()
web.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("OK"))
})
svc := adaptors.NewHTTPService(&http.Server{
        Addr:    ":8080",
        Handler: web,
})
svc.RegisterLifecycle("web", lf)

Add healthcheck service

The package github.com/g4s8/go-lifecycle/pkg/health has healthcheck http service which can monitor service statuses in lifecycle manager:

hs := health.NewService(":9999", lf)
hs.RegisterLifecycle(lf)

Documentation

Overview

Package lifecycle provides service lifecycle management.

This package provides a set of tools to manage service lifecycle, including startup and shutdown hooks, health checks, and service monitoring.

The main component of this package is `Lifecycle`, which is a service lifecycle manager. It provides methods to register startup and shutdown hooks, and to start and stop the service. `Lifecycle` also provides a method to subscribe to service state changes, which can be used to monitor the service state.

Lifecycle package also provides a `SignalHandler` component, which can be used to handle OS signals and stop the service on receiving a signal.

Adaptors package provides a set of adaptors to integrate with other packages, such as web server adaptor.

Health package provides a health check service, which can be used to check the service health.

Package overview:

  • `github.com/g4s8/go-lifecycle/pkg/lifecycle` - components to manage lifecycle
  • `github.com/g4s8/go-lifecycle/pkg/adaptors` - some common adaptors, e.g. http server adaptor
  • `github.com/g4s8/go-lifecycle/pkg/health` - healthcheck for services
  • `github.com/g4s8/go-lifecycle/pkg/types` - public types

Example: ```go package main

import (

"log"
"net/http"

"github.com/g4s8/go-lifecycle/pkg/adaptors"
"github.com/g4s8/go-lifecycle/pkg/health"
"github.com/g4s8/go-lifecycle/pkg/lifecycle"

)

func main() {
	web := http.NewServeMux()
	web.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("OK"))
	})
	svc := adaptors.NewHTTPService(&http.Server{
		Addr:    ":8080",
		Handler: web,
	})

	lf := lifecycle.New(lifecycle.DefaultConfig)
	svc.RegisterLifecycle("web", lf)
	hs := health.NewService(":9999", lf)
	hs.RegisterLifecycle(lf)
	lf.Start()
	sig := lifecycle.NewSignalHandler(lf, nil)
	sig.Start(lifecycle.DefaultShutdownConfig)
	if err := sig.Wait(); err != nil {
		log.Fatalf("shutdown error: %v", err)
	}
	log.Print("shutdown complete")
}

```

Directories

Path Synopsis
internal
pkg
adaptors
Package adaptors provides adaptors for common services.
Package adaptors provides adaptors for common services.
lifecycle
Package lifecycle provides a simple interface for managing the application lifecycle.
Package lifecycle provides a simple interface for managing the application lifecycle.
types
Package types exports public types for lifecycle.
Package types exports public types for lifecycle.

Jump to

Keyboard shortcuts

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