gs

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2024 License: MIT Imports: 6 Imported by: 5

README

GS

A lightweight generic graceful shutdown component

logo

Introduction

Graceful Shutdown is a common requirement for most services. It is a good practice to shutdown the service gracefully when the service receives a signal to terminate. The graceful shutdown process usually includes the following steps:

  1. Create TerminateSignal instance, and register the signal which want to be received.
  2. Register the resources which want to be closed when the service is terminated.
  3. Use WaitingForGracefulShutdown method to wait for the TerminateSignal instance to shutdown gracefully.

Advantage

  • Simple and easy to use
  • No third-party dependencies
  • Low memory usage
  • Support timeout signal
  • Support context
  • Support multiple signals

Installation

go get github.com/shengyanli1982/gs

Quick Start

GS is very simple, less code and easy to use. Just create TerminateSignal instances, register the resources which want to be closed when the service is terminated, and use WaitingForGracefulShutdown method to wait for the TerminateSignal instances to shutdown gracefully.

Methods

Create

  • NewTerminateSignal : Create a new TerminateSignal instance
  • NewDefaultTerminateSignal : Create a new TerminateSignal instance with default signals
  • NewTerminateSignalWithContext : Create a new TerminateSignal instance with context

[!TIP] The InfinityTerminateTimeout value is used to set the timeout signal to infinity. It means that the TerminateSignal instance will not be closed until Close method is called and the resources registered in the TerminateSignal instance are closed.

TerminateSignal

  • RegisterCancelCallback : Register the resources which want to be closed when the service is terminated
  • GetStopContext : Get the context of the TerminateSignal instance
  • Close : Close the TerminateSignal instance

Waiting

  • WaitingForGracefulShutdown : Use this method to wait for all TerminateSignal instances to shutdown gracefully
Example
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/shengyanli1982/gs"
)

// simulate a service
type testTerminateSignal struct{}

func (t *testTerminateSignal) Close() {
	fmt.Println("testTerminateSignal.Close()")
}

// simulate a service
type testTerminateSignal2 struct{}

func (t *testTerminateSignal2) Shutdown() {
	fmt.Println("testTerminateSignal2.Shutdown()")
}

// simulate a service
type testTerminateSignal3 struct{}

func (t *testTerminateSignal3) Terminate() {
	fmt.Println("testTerminateSignal3.Terminate()")
}

func main() {
	// Create TerminateSignal instance
	s := gs.NewDefaultTerminateSignal()

	// create resources which want to be closed when the service is terminated
	t1 := &testTerminateSignal{}
	t2 := &testTerminateSignal2{}
	t3 := &testTerminateSignal3{}

	// Register the close method of the resource which want to be closed when the service is terminated
	s.RegisterCancelCallback(tts.Close)

	// Create a goroutine to send a signal to the process after 2 seconds
	go func() {
		time.Sleep(2 * time.Second)
		p, err := os.FindProcess(os.Getpid())
		if err != nil {
			fmt.Println(err.Error())
		}
		err = p.Signal(os.Interrupt)
		if err != nil {
			fmt.Println(err.Error())
		}
	}()

	// Use WaitingForGracefulShutdown method to wait for the TerminateSignal instance to shutdown gracefully
	gs.WaitingForGracefulShutdown(s)

	fmt.Println("shutdown gracefully")
}

Result

# go run main.go
testTerminateSignal3.Terminate()
testTerminateSignal.Close()
testTerminateSignal2.Shutdown()
shutdown gracefully

Features

GS provides features not many but enough for most services.

Timeout Signal

TerminateSignal instance can be created with a timeout signal. When the timeout signal is received, the TerminateSignal instance will be closed not waiting for resources registered in the TerminateSignal instance will be closed.

[!TIP] The Timeout can fix the problem that the service cannot be closed due to the resource cannot be closed. But it is not recommended to use timeout signal, because it may cause the resource to be closed abnormally.

Example
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/shengyanli1982/gs"
)

// simulate a service
type testTerminateSignal struct{}

func (t *testTerminateSignal) Close() {
	time.Sleep(5 * time.Second)
}

func main() {
	// Create TerminateSignal instance
	s := gs.NewTerminateSignal(time.Second)  // timeout signal is set to 1 second

	// create a resource which want to be closed when the service is terminated
	t1 := &testTerminateSignal{}

	s.RegisterCancelCallback(tts.Close)

	// Create a goroutine to send a signal to the process after 2 seconds
	go func() {
		time.Sleep(2 * time.Second)
		p, err := os.FindProcess(os.Getpid())
		if err != nil {
			fmt.Println(err.Error())
		}
		err = p.Signal(os.Interrupt)
		if err != nil {
			fmt.Println(err.Error())
		}
	}()

	// Use WaitingForGracefulShutdown method to wait for the TerminateSignal instance to shutdown gracefully
	gs.WaitingForGracefulShutdown(s)

	fmt.Println("shutdown gracefully")
}

Documentation

Index

Constants

View Source
const InfinityTerminateTimeout = time.Duration(-1)

InfinityTerminateTimeout 无限大的超时时间 (Infinite timeout)

Variables

This section is empty.

Functions

func WaitingForGracefulShutdown

func WaitingForGracefulShutdown(sigs ...*TerminateSignal)

等待所有关闭信号 Wait for all shutdown signals

Types

type TerminateSignal

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

func NewDefaultTerminateSignal

func NewDefaultTerminateSignal() *TerminateSignal

创建一个默认的 TerminateSignal 实例,超时时间为无限大 Create a default TerminateSignal instance with infinite timeout

func NewTerminateSignal

func NewTerminateSignal(timeout time.Duration) *TerminateSignal

创建一个带有超时的 TerminateSignal 实例 Create a TerminateSignal instance with timeout

func NewTerminateSignalWithContext

func NewTerminateSignalWithContext(ctx context.Context, timeout time.Duration) *TerminateSignal

创建一个带有上下文和超时的 TerminateSignal 实例 Create a TerminateSignal instance with context and timeout

func (*TerminateSignal) Close

func (s *TerminateSignal) Close(wg *sync.WaitGroup)

Close 关闭 TerminateSignal 实例 Close the TerminateSignal instance

func (*TerminateSignal) GetStopContext added in v0.1.1

func (s *TerminateSignal) GetStopContext() context.Context

获取停止信号的 Context Get the Context of the stop signal

func (*TerminateSignal) RegisterCancelCallback added in v0.1.1

func (s *TerminateSignal) RegisterCancelCallback(callbacks ...func())

注册需要取消的回调函数 Register the callback function to be canceled

Jump to

Keyboard shortcuts

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