lifecycle

package module
v0.0.2 Latest Latest
Warning

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

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

README

Introducing a powerful and versatile Go library for managing the lifecycle of your applications!

It is designed to be simple, yet flexible, giving you complete control over configuring and running multiple services within a single application. With built-in tools for monitoring service state, implementing graceful shutdowns, and conducting health checks, this library provides everything you need to ensure your application runs smoothly.

CI GoDoc

Key Features

  • Simple and flexible Go lifecycle manager library.
  • Components to manage application lifecycle, handle system signals for graceful shutdowns, and built-in health-check service.
  • Adapters for common scenarios, such as HTTP servers.
  • No reflection or magic behind the scenes, just static types.
  • Flexible configuration options for both the lifecycle manager and each individual service.

How go-lifecycle Compares to Others

While our library is similar in some aspects to the github.com/uber-go/fx library, there are several main differences:

  • This library is not a DI container, only a lifecycle manager.
  • This library uses only static types, without any reflection or magic behind the scenes.
  • This library offers more flexibility in configuration options.

Get Started

See Usage examples below and check out the /examples directory to see it in action!

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) // start it async
sig.Wait() // wait for signal

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)

Contributing

Documentation

Overview

Package lifecycle is a powerful toolset for managing the lifecycle of services, including startup and shutdown hooks, health checks, and service monitoring.

At the heart of the package is the Lifecycle component, which acts as a service lifecycle manager. It provides a variety of methods for registering startup and shutdown hooks, as well as starting and stopping the service. Additionally, the Lifecycle component can be used to subscribe to service state changes, which can be a valuable tool for monitoring the service state.

In addition to the Lifecycle component, the package includes a SignalHandler component, which can be used to gracefully handle OS signals and stop the service when necessary.

To integrate the lifecycle package with other packages, the adaptors package provides a variety of adaptors. For example, the http server adaptor allows for seamless integration with web servers.

Finally, the health package provides a health check service that can be used to monitor the health of the service.

Package Overview:

  • github.com/g4s8/go-lifecycle/pkg/lifecycle: Components for managing service lifecycle
  • github.com/g4s8/go-lifecycle/pkg/adaptors: Common adaptors, such as the http server adaptor
  • github.com/g4s8/go-lifecycle/pkg/health: Healthcheck service for monitoring service health
  • github.com/g4s8/go-lifecycle/pkg/types: Public types used in the package.

Example:

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