worker_manager

package module
v0.0.9 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2023 License: MIT Imports: 9 Imported by: 6

README

worker_manager

golang-ci


Overview

Use observer partern to easily manage the start and stop of workers.

How to get
go get github.com/vearne/worker_manager
default exit signal

syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT

Example
package main

import (
	"context"
	"github.com/gin-gonic/gin"
	wm "github.com/vearne/worker_manager"
	"log"
	"net/http"
	"syscall"
	"time"
)

func main() {
	app := wm.NewApp()
	// add 2 load worker
	app.AddWorker(NewLoadWorker())
	app.AddWorker(NewLoadWorker())
	// add 1 web worker
	app.AddWorker(NewWebServer())

	// optional
	// If not set, the default value will be used
	app.SetExitSigs(syscall.SIGTERM, syscall.SIGQUIT)
	// optional
	// Configuring Ignore Signals
	app.SetIgnoreSigs(syscall.SIGINT)
	app.Run()
}

// some worker

type LoadWorker struct {
	RunningFlag *wm.AtomicBool
	ExitedFlag  chan struct{}
	ExitChan    chan struct{}
}

func NewLoadWorker() *LoadWorker {
	worker := &LoadWorker{}
	worker.RunningFlag = wm.NewAtomicBool(true)
	worker.ExitedFlag = make(chan struct{})
	worker.ExitChan = make(chan struct{})
	return worker
}

func (worker *LoadWorker) Start() {
	log.Println("[start]LoadWorker")
	for worker.RunningFlag.IsTrue() {
		select {
		case <-time.After(1 * time.Minute):
			//do some thing
			log.Println("LoadWorker do something")
			time.Sleep(time.Second * 3)
		case <-worker.ExitChan:
			// do some clean task
			log.Println("LoadWorker execute exit logic")
		}
	}
	close(worker.ExitedFlag)
}

func (worker *LoadWorker) Stop() {
	log.Println("LoadWorker exit...")
	worker.RunningFlag.Set(false)
	close(worker.ExitChan)

	<-worker.ExitedFlag
	log.Println("[end]LoadWorker")
}

type WebServer struct {
	Server *http.Server
}

func NewWebServer() *WebServer {
	return &WebServer{}
}

func (worker *WebServer) Start() {
	log.Println("[start]WebServer")

	ginHandler := gin.Default()
	ginHandler.GET("/", func(c *gin.Context) {
		c.Data(http.StatusOK, "text/plain", []byte("hello world!"))
	})
	worker.Server = &http.Server{
		Addr:           ":9527",
		Handler:        ginHandler,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	worker.Server.ListenAndServe()
}

func (worker *WebServer) Stop() {
	log.Println("WebServer exit...")
	cxt, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	// gracefull exit web server
	err := worker.Server.Shutdown(cxt)
	if err != nil {
		log.Printf("shutdown error, %v", err)
	}
	log.Println("[end]WebServer exit")
}
go build main.go
# Start service
./main
# Send a SIGTERM signal to make the service exit gracefully
# Please replace pid by yourself
kill -15 <pid> 

output

2022/06/14 11:08:44 [start]WebServer
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

2022/06/14 11:08:44 [start]LoadWorker
[GIN-debug] GET    /                         --> main.(*WebServer).Start.func1 (3 handlers)
2022/06/14 11:08:44 [start]LoadWorker
[GIN] 2022/06/14 - 11:08:52 | 200 |       6.958µs |       127.0.0.1 | GET      "/"
2022/06/14 11:09:08 WebServer exit...
2022/06/14 11:09:08 LoadWorker exit...
2022/06/14 11:09:08 [end]LoadWorker
2022/06/14 11:09:08 LoadWorker execute exit logic
2022/06/14 11:09:08 LoadWorker exit...
2022/06/14 11:09:08 [end]LoadWorker
2022/06/14 11:09:08 LoadWorker execute exit logic
2022/06/14 11:09:08 [end]WebServer exit

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

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

func NewApp

func NewApp() *App

func (*App) AddWorker

func (a *App) AddWorker(w Worker)

func (*App) Run

func (a *App) Run()

func (*App) SetExitSigs added in v0.0.6

func (a *App) SetExitSigs(sig ...os.Signal)

func (*App) SetIgnoreSigs added in v0.0.6

func (a *App) SetIgnoreSigs(sig ...os.Signal)

type AtomicBool added in v0.0.2

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

atomicBool is a wrapper around uint32 for usage as a boolean value with atomic access.

func NewAtomicBool added in v0.0.2

func NewAtomicBool(flag bool) *AtomicBool

func (*AtomicBool) IsSet added in v0.0.2

func (ab *AtomicBool) IsSet() bool

IsSet returns whether the current boolean value is true

func (*AtomicBool) IsTrue added in v0.0.2

func (ab *AtomicBool) IsTrue() bool

func (*AtomicBool) Set added in v0.0.2

func (ab *AtomicBool) Set(value bool)

Set sets the value of the bool regardless of the previous value

type Worker

type Worker interface {
	Start()
	Stop()
}

type WorkerManager

type WorkerManager struct {
	sync.WaitGroup

	WorkerSlice []Worker
	// contains filtered or unexported fields
}

func NewWorkerManager

func NewWorkerManager() *WorkerManager

func (*WorkerManager) AddWorker

func (wm *WorkerManager) AddWorker(w Worker)

func (*WorkerManager) Start

func (wm *WorkerManager) Start()

func (*WorkerManager) Stop

func (wm *WorkerManager) Stop()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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