Skip to content

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

License

Notifications You must be signed in to change notification settings

phith0n/vindicator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

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

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages