github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 "launchpad.net/tomb" 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 u := &terminationWorker{} 34 go func() { 35 defer u.tomb.Done() 36 u.tomb.Kill(u.loop()) 37 }() 38 return u 39 } 40 41 func (u *terminationWorker) Kill() { 42 u.tomb.Kill(nil) 43 } 44 45 func (u *terminationWorker) Wait() error { 46 return u.tomb.Wait() 47 } 48 49 func (u *terminationWorker) loop() (err error) { 50 c := make(chan os.Signal, 1) 51 signal.Notify(c, TerminationSignal) 52 defer signal.Stop(c) 53 select { 54 case <-c: 55 return worker.ErrTerminateAgent 56 case <-u.tomb.Dying(): 57 return tomb.ErrDying 58 } 59 }