github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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/tomb.v1" 12 13 "github.com/juju/juju/worker" 14 ) 15 16 // TerminationSignal is the signal that 17 // indicates the agent should terminate 18 // and uninstall itself. 19 // 20 // We do not use SIGTERM as SIGTERM is the 21 // default signal used to initiate a graceful 22 // shutdown. 23 const TerminationSignal = syscall.SIGABRT 24 25 type terminationWorker struct { 26 tomb tomb.Tomb 27 } 28 29 // NewWorker returns a worker that waits for a 30 // TerminationSignal signal, and then exits 31 // with worker.ErrTerminateAgent. 32 func NewWorker() worker.Worker { 33 var w terminationWorker 34 c := make(chan os.Signal, 1) 35 signal.Notify(c, TerminationSignal) 36 go func() { 37 defer w.tomb.Done() 38 defer signal.Stop(c) 39 w.tomb.Kill(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 worker.ErrTerminateAgent 56 case <-w.tomb.Dying(): 57 return tomb.ErrDying 58 } 59 }