gs

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2023 License: MIT Imports: 6 Imported by: 5

README

G.S

logo

A lightweight generic graceful shutdown component

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.

Example
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/shengyanli1982/gs"
)

type testTerminateSignal struct{}

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

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

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

	// Register the close method of the resource which want to be closed when the service is terminated
	s.CancelCallbacksRegistry(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 {
			assert.Fail(t, err.Error())
		}
		err = p.Signal(os.Interrupt)
		if err != nil {
			assert.Fail(t, err.Error())
		}
	}()

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

	fmt.Println("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 (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/shengyanli1982/gs"
)

type testTerminateSignal struct{}

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

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

	tts := &testTerminateSignal{}

	s.CancelCallbacksRegistry(tts.Close)

	go func() {
		time.Sleep(2*time.Second)
		p, err := os.FindProcess(os.Getpid())
		if err != nil {
			assert.Fail(t, err.Error())
		}
		err = p.Signal(os.Interrupt)
		if err != nil {
			assert.Fail(t, err.Error())
		}
	}()

	WaitingForGracefulShutdown(s)

	fmt.Println("shutdown gracefully")
}

Documentation

Index

Constants

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

ConstInfinityTerminateTimeout 无限大的超时时间 (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) CancelCallbacksRegistry

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

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

func (*TerminateSignal) Close

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

Close 关闭 TerminateSignal 实例 Close the TerminateSignal instance

func (*TerminateSignal) GetStopCtx

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

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

Jump to

Keyboard shortcuts

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