Code Monkey home page Code Monkey logo

littleboss's Introduction

littleboss: self-supervising Go binaries

A Go package, littleboss lets you turn your program into a a self-supervising binary. It starts itself as a child process, monitors its life cycle, reloads it if it exits, and can be instructed to replace it with a new binary.

The supervisor can open sockets for you and share them across reloads of your program, ensuring no connections are dropped.

You can install it with:

go get crawshaw.io/littleboss

Make a program use littleboss by modifying the main function:

func main() {
	lb := littleboss.New("service-name")
	lb.Run(func(ctx context.Context) {
		// main goes here, exit when <-ctx.Done()
	})
}

The service name is used to identify which program the supervisor will control.

Usage

By default the supervisor is bypassed and the program executes directly. A flag, -littleboss, is added to the binary. It can be used to start a supervised binary and manage it:

$ mybin &                     # binary runs directly, no child process
$ mybin -littleboss=start &   # supervisor is created
$ mybin2 -littleboss=reload   # child is replaced by new mybin2 process
$ mybin -littleboss=stop      # supervisor and child are shut down

Configuration

Supervisor options are baked into the binary. The littleboss struct type contains fields that can be set before calling the Run method to configure the supervisor. Options include reloading the previous binary if a reload fails, controlling how long an exiting program has to turn down its connections, and specifying exactly what flags control and are passed by littleboss.

An HTTP server example

func main() {
	lb := littleboss.New("myblog")
	flagHTTPS := lb.Listener("https", "tcp", ":443", "address")
	lb.Run(func(ctx context.Context) {
		httpMain(ctx, flagHTTPS.Listener())
	})
}

func httpMain(ctx context.Context, ln net.Listener) {
	srv := &http.Server{
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,
		IdleTimeout:  60 * time.Second,
		Handler:      blogHandler,
	}
	go func() {
		if err := srv.ServeTLS(ln, "certfile", "keyfile"); err != nil {
			if err == http.ErrServerClosed {
				return
			}
			log.Fatal(err)
		}
	}()

	<-ctx.Done()
	srv.Shutdown(ctx)
}

littleboss's People

Contributors

crawshaw avatar creachadair avatar frozzare avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

littleboss's Issues

why listen unix socket?

hi:
I was thinking write something like this before, when I found you work, I think this is really what I want, and I read a little about the code, I am a little confused about the unix socket, I think without the unix socket listener, all the command flags can also be handled. So why listen on an unix socket to handle command?

pflag integration is broken

Disabling for now.

--- FAIL: TestPFlag (0.58s)
    littleboss_test.go:293: exit status 2: flag provided but not defined: -mylb
        Usage of /var/folders/5m/psbp5kd94gl7b7q7xc70p4w00000gn/T/littleboss_test_337893288/bin/pflag:
FAIL
exit status 1
FAIL    crawshaw.io/littleboss  0.592s```

Unhandled Error

Hello,

Was taking a look as I may have a need for something like this, and out of habit I ran megacheck against the repo.

You seem to have an error on line 522 that will end up getting ignored by the next call assign to that variable on 525.

I'm still reading the code and understanding the approach so, not sure if this represents a real issue or is just a false-positive but I thought I would pass it along.

Very cool stuff, all the same! Thanks for building this!

TestStartStopReload is flaky

Running on go version go1.12.1 darwin/amd64:

$ go test
--- FAIL: TestStartStopReload (0.62s)
    littleboss_test.go:153: echo_server address: "addr=[::]:54901"
    littleboss_test.go:176: reload failed: exit status 1: reload of echo_server failed: wait: no child processes
        
        echo_server output:
        SupervisorInit called
        addr=[::]:54901
        littleboss: reload requested
        entering lameduck mode
        littleboss: exit: wait: no child processes
FAIL
exit status 1
FAIL    crawshaw.io/littleboss  3.980s

default flag value can fail to pass through on reload

Added a flag to a process, so on -littleboss=reload it tried and failed to use the default value:

panic: littleboss: child listener flag "myaddr" value does not include fd: ":8465"

goroutine 1 [running]:
crawshaw.io/littleboss.(*Littleboss).child(0xc0000e4dc0, 0x9a2848)
        /Users/crawshaw/go/src/crawshaw.io/littleboss/littleboss.go:879 +0xb1e
crawshaw.io/littleboss.(*Littleboss).Run(0xc0000e4dc0, 0x9a2848)
        /Users/crawshaw/go/src/crawshaw.io/littleboss/littleboss.go:247 +0x961
main.main()
        /Users/crawshaw/go/src/spilled.ink/smsmtpd/main.go:64 +0x2bc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.