diff --git a/client/alloc_runner.go b/client/alloc_runner.go index a366ee18351..f4613ad67cd 100644 --- a/client/alloc_runner.go +++ b/client/alloc_runner.go @@ -53,6 +53,7 @@ type AllocRunner struct { destroy bool destroyCh chan struct{} destroyLock sync.Mutex + waitCh chan struct{} } // allocRunnerState is used to snapshot the state of the alloc runner @@ -74,6 +75,7 @@ func NewAllocRunner(logger *log.Logger, config *config.Config, updater AllocStat taskStatus: make(map[string]taskStatus), updateCh: make(chan *structs.Allocation, 8), destroyCh: make(chan struct{}), + waitCh: make(chan struct{}), } return ar } @@ -258,6 +260,7 @@ func (r *AllocRunner) setTaskStatus(taskName, status, desc string) { // Run is a long running goroutine used to manage an allocation func (r *AllocRunner) Run() { + defer close(r.waitCh) go r.dirtySyncState() // Check if the allocation is in a terminal status @@ -376,3 +379,8 @@ func (r *AllocRunner) Destroy() { r.destroy = true close(r.destroyCh) } + +// WaitCh returns a channel to wait for termination +func (r *AllocRunner) WaitCh() <-chan struct{} { + return r.waitCh +} diff --git a/client/client.go b/client/client.go index 148cee4c7ac..744bad87691 100644 --- a/client/client.go +++ b/client/client.go @@ -184,6 +184,15 @@ func (c *Client) Shutdown() error { if c.shutdown { return nil } + + // Destroy all the running allocations. + if c.config.DevMode { + for _, ar := range c.allocs { + ar.Destroy() + <-ar.WaitCh() + } + } + c.shutdown = true close(c.shutdownCh) c.connPool.Shutdown()