exit

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

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

Go to latest
Published: Jan 20, 2016 License: Apache-2.0 Imports: 9 Imported by: 0

README

An exit strategy for go routines.

Build Status Code Coverage Documentation

The library helps to end the go routines in your program and collects potential errors.

Install

go get github.com/simia-tech/go-exit

Example (main)

func main() {
	exit.Main.SetTimeout(2 * time.Second)

	counterExitSignal := exit.Main.NewSignal("counter")
	go func() {
		counter := 0

		var reply exit.Reply
		for reply == nil {
			select {
			case reply = <-counterExitSignal.Chan:
				break
			case <-time.After(1 * time.Second):
				counter++
				fmt.Printf("%d ", counter)
			}
		}

		switch {
		case counter%5 == 0:
			// Don't send a return via reply to simulate
			// an infinite running go routine. The timeout
			// should be hit in this case.
		case counter%2 == 1:
			reply.Err(fmt.Errorf("exit on the odd counter %d", counter))
		default:
			reply.Ok()
		}
	}()

	if report := exit.Main.ExitOn(syscall.SIGINT); report != nil {
		fmt.Println()
		report.WriteTo(os.Stderr)
		os.Exit(-1)
	}
	fmt.Println()
}

The default exit exit.Main should be used by the main program to exit it's go routines. If go-exit is used in a library, a separate exit should be created and used to end the library's go routines. This way the library stays independent from other exit code.

Example (library)

type Server struct {
	Address string
	exit    *exit.Exit
}

func New(address string) *Server {
	return &Server{
		Address: address,
		exit:    exit.New("server"),
	}
}

func (s *Server) Open() error {
	listener, err := net.Listen("tcp", s.Address)
	if err != nil {
		return err
	}

	signal := s.exit.NewSignal("acceptor")
	go func() {
		var reply exit.Reply

		go func() {
			for {
				connection, err := listener.Accept()
				if err != nil {
					if reply != nil && strings.Contains(
						err.Error(), "closed network connection") {
						reply.Ok()
					} else {
						reply.Err(err)
					}
					return
				}
				log.Printf("connected %v", connection.RemoteAddr())
				// handle connection
			}
		}()

		reply = <-signal.Chan
		if err := listener.Close(); err != nil {
			reply.Err(err)
		}
	}()

	return nil
}

func (s *Server) Close() error {
	if report := s.exit.Exit(); report != nil {
		return report
	}
	return nil
}

License

The project is licensed under Apache 2.0.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTimeout = errors.New("timeout")
)

Defines errors.

View Source
var Main = New("main")

Main defines the main exit. This exit should be used by the main program. Libraries should create their own exit.

Functions

This section is empty.

Types

type Exit

type Exit struct {
	Name string
	// contains filtered or unexported fields
}

Exit defines an exit that contains multiple SignalChans.

func New

func New(name string) *Exit

New returns a new exit with the provided name.

func (*Exit) AfterAll

func (e *Exit) AfterAll(fn func(*Report))

AfterAll registers a callback function that is called after all actors has exited.

func (*Exit) AfterEach

func (e *Exit) AfterEach(fn func(error))

AfterEach registers a callback function that is called after each actor that has exited.

func (*Exit) Exit

func (e *Exit) Exit() *Report

Exit sends an ErrChan through all the previously generated SignalChans and waits until all returned an error or nil. The received errors will be returned in an error report.

func (*Exit) ExitOn

func (e *Exit) ExitOn(osSignales ...os.Signal) *Report

ExitOn blocks until the process receives one of the provided signals and than calls Exit.

func (*Exit) HasTimeout

func (e *Exit) HasTimeout() bool

HasTimeout returns true if a timeout is set.

func (*Exit) NewSignal

func (e *Exit) NewSignal(name string) *Signal

NewSignal creates a new Signal, attaches it to the exit and returns it.

func (*Exit) SetTimeout

func (e *Exit) SetTimeout(value time.Duration)

SetTimeout sets a timeout for the actors to end during the exit process.

type Reply

type Reply chan error

Reply defines a channel of errors that can be used to deliver back an error after an actor has shut down.

func (Reply) Err

func (r Reply) Err(err error)

Err reports back the provided error.

func (Reply) Ok

func (r Reply) Ok()

Ok report back no error. Same as Err(nil).

type Report

type Report struct {
	ExitName string
	// contains filtered or unexported fields
}

Report defines the report of the exit process. It contains map of all signal names with their returned error.

func NewReport

func NewReport(exitName string) *Report

NewReport returns a new initialized Report.

func (*Report) Error

func (r *Report) Error() string

Error implements the error interface.

func (*Report) Get

func (r *Report) Get(name string) error

Get return the error for the provided name.

func (*Report) Len

func (r *Report) Len() int

Len returns the number of errors in the report.

func (*Report) Set

func (r *Report) Set(name string, err error)

Set the provided error for the provided name.

func (*Report) WriteTo

func (r *Report) WriteTo(w io.Writer) (int64, error)

WriteTo prints the report to the provided io.Writer.

type Signal

type Signal struct {
	Name string
	Chan chan Reply
	// contains filtered or unexported fields
}

Signal defines an exit signal signal for a single actor.

func NewSignal

func NewSignal(name string) *Signal

NewSignal returns a new initialized signal with the provided name.

func (*Signal) AfterExit

func (s *Signal) AfterExit(fn func(error))

AfterExit registers a callback function that is called after the exit has been performed.

func (*Signal) Exit

func (s *Signal) Exit() (err error)

Exit performs the exit process for this specific signal.

func (*Signal) HasTimeout

func (s *Signal) HasTimeout() bool

HasTimeout returns true if a timeout is set.

func (*Signal) SetTimeout

func (s *Signal) SetTimeout(value time.Duration)

SetTimeout sets the timeout for this specific exit signal to complete. If no or zero timeout is set, the exit process can last forever.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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