vindicator

package module
v0.0.0-...-c04ce55 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2022 License: MIT Imports: 4 Imported by: 0

README

Vindicator

Vindicator is a lightweight Golang library that is designed to hold and check any blocking function, e.g. subprocess, network connection...

Contents

Installation

go get -u github.com/phith0n/vindicator

Quick Start

You have to write a struct I call it "Worker", that implements vindicator.Worker:

type Worker interface {
    Work(ctx context.Context) error // the worker() must be a blocking function
    GetRunning() bool
    SetRunning(bool)
}

There are 3 functions in the Worker interface:

  • Work (ctx context.Context) error this function must be a blocking function. the monitor will start a new worker if this function exit unexpected.
  • SetRunning(run bool) this function should set the running status of the worker
  • GetRunning() bool this function should return current running status

The Work function accepts a context object, it must control the lifecycle of your worker.

For example, if you want to start a subprocess and check it regularly if it is still running, here is the struct implement:

type ProcessWorker struct {
    isRunning bool
}

// Work must be a blocking function
func (pw *ProcessWorker) Work(ctx context.Context) error {
    cmd := exec.CommandContext(ctx, "sleep", "1h")
    if err := cmd.Start(); err != nil {
        return err
    }

    if err := cmd.Wait(); err != nil {
        return err
    }

    return nil
}

func (pw *ProcessWorker) SetRunning(run bool) {
    pw.isRunning = run
}

func (pw *ProcessWorker) GetRunning() bool {
    return pw.isRunning
}

Then, use Vindicator to start and monitor the ProcessWorker:

ctx := context.Background()
worker := ProcessWorker{}
v := vindicator.NewVindicator(&worker, 2)

// you can use event listener to execute some callback function
v.On("monitor:start", func(v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("start monitor")
})
v.On("monitor:working", func (v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("process is working normally...")
})
v.On("monitor:interrupt", func (v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("process is stopped unexpected, try to restart it...")
})
v.On("monitor:stop", func (v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("stop monitor")
})
v.On("worker:start", func (v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("start worker")
})
v.On("worker:stop", func (v *vindicator.Vindicator, args ...interface{}) {
    fmt.Println("stop worker")
})

// run worker and monitor in background
go v.Start(ctx)
go v.Monitor(ctx)

// to wait sometime...
timer := time.NewTimer(time.Second * 10)
<-timer.C

// demonstrate how to stop the worker and the monitor manual
v.Stop()

This example checks the process running status every 2 seconds, and stop it after 10 seconds.

The output:

start worker
start monitor
process is working normally...
process is working normally...
process is working normally...
process is working normally...
process is working normally...
stop monitor
stop worker

The full example code you can find here.

API Reference

Vindicator Struct

Create a new Vindicator:

v := vindicator.NewVindicator(&worker, 2)

The first argument is your custom Worker implements, the second argument is the monitor cycle time by seconds.

Worker Interface
type Worker interface {
    Work(ctx context.Context) error // the worker() must be a blocking function
    GetRunning() bool
    SetRunning(bool)
}
Event

There are several events that you can listen and execute custom callback functions:

  • monitor:start trigger when monitor is started
  • monitor:stop trigger when monitor is stopped manual
  • monitor:interrupt trigger when monitor is stopped unexpected
  • monitor:working trigger when monitor works at cycle run
  • worker:start trigger when worker is started
  • worker:stop trigger when worker is stopped
  • worker:error trigger when an error is raised by worker

Use Vindicator.On to register a listener:

type VindicatorFn func(v *Vindicator, args ...interface{})

func (v *Vindicator) On(eventName string, callback VindicatorFn) {
	// ...
}

FAQ

When should I use this library?

You can use github.com/phith0n/vindicator when you are going to run a blocking function and maintain its status. For example, the subprocess, the TCP long connection, the Websocket connection, and any other program like these.

Is there a document for this library?

No yet. But there are only 100+ lines code for this project, you can kindly read the code and understand it by yourself.

Contributing

If you'd like to help out with the project. You can put up a Pull Request.

License

The Vindicator is open-sourced software licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Vindicator

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

func NewVindicator

func NewVindicator(worker Worker, interval int) *Vindicator

func (*Vindicator) Monitor

func (v *Vindicator) Monitor(ctx context.Context)

func (*Vindicator) On

func (v *Vindicator) On(eventName string, callback VindicatorFn)

func (*Vindicator) SetRunning

func (v *Vindicator) SetRunning()

func (*Vindicator) SetStopped

func (v *Vindicator) SetStopped()

func (*Vindicator) Start

func (v *Vindicator) Start(ctx context.Context) error

func (*Vindicator) Stop

func (v *Vindicator) Stop()

func (*Vindicator) Wait

func (v *Vindicator) Wait()

type VindicatorFn

type VindicatorFn func(v *Vindicator, args ...interface{})

type Worker

type Worker interface {
	Work(ctx context.Context) error // the worker() must be a blocking function
	GetRunning() bool
	SetRunning(bool)
}

Jump to

Keyboard shortcuts

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