github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/terminationworker/worker.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package terminationworker
     5  
     6  import (
     7  	"os"
     8  	"os/signal"
     9  	"syscall"
    10  
    11  	"gopkg.in/juju/worker.v1"
    12  	"gopkg.in/tomb.v2"
    13  
    14  	jworker "github.com/juju/juju/worker"
    15  )
    16  
    17  // TerminationSignal is the signal that
    18  // indicates the agent should terminate
    19  // and uninstall itself.
    20  //
    21  // We do not use SIGTERM as SIGTERM is the
    22  // default signal used to initiate a graceful
    23  // shutdown.
    24  const TerminationSignal = syscall.SIGABRT
    25  
    26  type terminationWorker struct {
    27  	tomb tomb.Tomb
    28  }
    29  
    30  // NewWorker returns a worker that waits for a
    31  // TerminationSignal signal, and then exits
    32  // with worker.ErrTerminateAgent.
    33  func NewWorker() worker.Worker {
    34  	var w terminationWorker
    35  	c := make(chan os.Signal, 1)
    36  	signal.Notify(c, TerminationSignal)
    37  	w.tomb.Go(func() error {
    38  		defer signal.Stop(c)
    39  		return w.loop(c)
    40  	})
    41  	return &w
    42  }
    43  
    44  func (w *terminationWorker) Kill() {
    45  	w.tomb.Kill(nil)
    46  }
    47  
    48  func (w *terminationWorker) Wait() error {
    49  	return w.tomb.Wait()
    50  }
    51  
    52  func (w *terminationWorker) loop(c <-chan os.Signal) (err error) {
    53  	select {
    54  	case <-c:
    55  		return jworker.ErrTerminateAgent
    56  	case <-w.tomb.Dying():
    57  		return tomb.ErrDying
    58  	}
    59  }