bark

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2019 License: Apache-2.0, MIT Imports: 14 Imported by: 0

README

bark

a golang watchdog for fast detection and restart of child processes

summary

Watch a child process and get notified immediately upon status change (such as termination). Remedies deficiency in the Go stdlib.

relevant inspiration:

a) detection of child process failure on OSX using the golang stdlib os.Process.Wait can take 30 seconds. Ouch.

b) Ian Lance Taylor suggested a Wait4 approach in this thread, and Igor Bukanov indicates it worked well for his use case; I confirm here that response is rapid.

http://grokbase.com/t/gg/golang-nuts/157dmnz8dq/go-nuts-os-process-wait-and-signals-before-process-dies

https://groups.google.com/forum/#!searchin/golang-nuts/os.Process.Wait$20and$20signals$20before$20process$20dies/golang-nuts/Xr7TP_yF5dQ/ksjZzddYgpcJ

what bark provides

The bark library provides the ability to monitor a child process, to automatically restart it if it fails, and to shut it down (SIGKILL or kill -9) upon request.

Simple and fast.

use / example

import (
  "github.com/betable/bark"
)

...
watcher := NewWatchdog(nil, "/path/to/child/executable")
watcher.Start() // launchs proc, automatically restarts it

// give it a second to get started
time.Sleep(2 * time.Millisecond)

// current Process ID is available here; if 0 then
// it is between restarts and you should poll again.
pid := <-watcher.CurrentPid

// ready to stop both child and watchdog
watcher.TermChildAndStopWatchdog <- true

// wait for shutdown of child and watchdog to complete
<-watcher.Done
fmt.Print("watchdog and child pid shutdown.\n")
...
rarely needed

Also available, the ReqStopWatchdog channel will shutdown only the watchdog, and leave the child process unmonitored:

watcher.ReqStopWatchdog <- true

Copyright (c) 2016 Betable.com and Rubicon Media, LLC.

License: Apache 2.0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Sysname string
View Source
var TimedOut = errors.New("TimedOut")
View Source
var Verbose bool // set to true to debug
View Source
var Working bool // currently under investigation

Functions

func DarwinOpenFiles

func DarwinOpenFiles(pid int) []string

func DarwinPs

func DarwinPs() *map[int]bool

func DirExists

func DirExists(name string) bool

func FileExists

func FileExists(name string) bool

func FileSize

func FileSize(name string) (int64, error)

func IsNumberString

func IsNumberString(s string) bool

func LinuxOpenFiles

func LinuxOpenFiles(pid int) []string

func LinuxPs

func LinuxPs() *map[int]bool

func OneshotAndWait

func OneshotAndWait(pathToProcess string, timeOut time.Duration, args ...string) (int, error)

OneshotAndWait runs the command pathToProcess with the given args, and returns the exit code of the process. You may need to divide the exit code by 256 to get what you expect, at least on OSX.

With timeOut of 0 we wait forever and return the exitcode and an error of nil. Otherwise we return 0 and the TimedOut error if we timed-out waiting for the child process to finish.

func OpenFiles

func OpenFiles(pid int) []string

func P

func P(format string, stuff ...interface{})

func ProcessTable

func ProcessTable() *map[int]bool

func Q

func Q(quietly_ignored ...interface{})

func SetDiff

func SetDiff(a, b []string) []string

func ShowStrings

func ShowStrings(s []string)

func TSPrintf

func TSPrintf(format string, a ...interface{})

time-stamped printf

func VPrintf

func VPrintf(format string, a ...interface{})

func WPrintf

func WPrintf(format string, a ...interface{})

func WaitForShutdownWithTimeout

func WaitForShutdownWithTimeout(pid int, timeout time.Duration) error

Types

type Watchdog

type Watchdog struct {
	Ready                       chan bool
	RestartChild                chan bool
	ReqStopWatchdog             chan bool
	TermChildAndStopWatchdog    chan bool
	Done                        chan bool
	CurrentPid                  chan int
	StopWatchdogAfterChildExits chan bool
	ExitCode                    int

	PathToChildExecutable string
	Args                  []string
	Attr                  os.ProcAttr
	// contains filtered or unexported fields
}

func NewOneshotReaper

func NewOneshotReaper(
	attr *os.ProcAttr,
	pathToChildExecutable string,
	args ...string) *Watchdog

NewOneshotReaper() is just like NewWatchdog, except that it also does two things:

a) sets a flag so that the watchdog won't restart the child process after it finishes.

and

b) the watchdog goroutine will itself exit once the child exists--after cleaning up. Cleanup means we don't leave zombies and we call go's os.Process.Release() to release associated resources after the child exits.

You still need to call Start(), just like after NewWatchdog().

func NewWatchdog

func NewWatchdog(
	attr *os.ProcAttr,
	pathToChildExecutable string,
	args ...string) *Watchdog

NewWatchdog creates a Watchdog structure but does not launch it or its child process until Start() is called on it. The attr argument sets function attributes such as environment and open files; see os.ProcAttr for details. Also, attr can be nil here, in which case and empty os.ProcAttr will be supplied to the os.StartProcess() call.

func Oneshot

func Oneshot(pathToProcess string, args ...string) (*Watchdog, error)

Oneshot() combines NewOneshotReaper() and Start(). In other words, we start the child once. We don't restart once it finishes. Instead we just reap and cleanup. The returned pointer's Done channel will be closed when the child process and watchdog goroutine have finished.

func StartAndWatch

func StartAndWatch(pathToProcess string, args ...string) (*Watchdog, error)

StartAndWatch() is the convenience/main entry API. pathToProcess should give the path to the executable within the filesystem. If it dies it will be restarted by the Watchdog.

func (*Watchdog) AlreadyDone

func (w *Watchdog) AlreadyDone() bool

func (*Watchdog) GetErr

func (w *Watchdog) GetErr() error

func (*Watchdog) SetErr

func (w *Watchdog) SetErr(err error)

func (*Watchdog) Start

func (w *Watchdog) Start()

see w.err for any error after w.Done

func (*Watchdog) Stop

func (w *Watchdog) Stop() error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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