github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/workertest/workers.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package workertest
     5  
     6  import (
     7  	"gopkg.in/tomb.v1"
     8  
     9  	"github.com/juju/juju/worker"
    10  )
    11  
    12  // NewErrorWorker returns a Worker that runs until Kill()ed; at which point it
    13  // fails with the supplied error. The caller takes responsibility for causing
    14  // it to be Kill()ed, lest the goroutine be leaked, but the worker has no
    15  // outside interactions or safety concerns so there's no particular need to
    16  // Wait() for it.
    17  func NewErrorWorker(err error) worker.Worker {
    18  	w := &errorWorker{err: err}
    19  	go func() {
    20  		defer w.tomb.Done()
    21  		<-w.tomb.Dying()
    22  	}()
    23  	return w
    24  }
    25  
    26  type errorWorker struct {
    27  	tomb tomb.Tomb
    28  	err  error
    29  }
    30  
    31  // Kill is part of the worker.Worker interface.
    32  func (w *errorWorker) Kill() {
    33  	w.tomb.Kill(w.err)
    34  }
    35  
    36  // Wait is part of the worker.Worker interface.
    37  func (w *errorWorker) Wait() error {
    38  	return w.tomb.Wait()
    39  }
    40  
    41  // NewDeadWorker returns a Worker that's already dead, and always immediately
    42  // returns the supplied error from Wait().
    43  func NewDeadWorker(err error) worker.Worker {
    44  	return &deadWorker{err: err}
    45  }
    46  
    47  type deadWorker struct {
    48  	err error
    49  }
    50  
    51  // Kill is part of the worker.Worker interface.
    52  func (w *deadWorker) Kill() {}
    53  
    54  // Wait is part of the worker.Worker interface.
    55  func (w *deadWorker) Wait() error {
    56  	return w.err
    57  }
    58  
    59  // NewForeverWorker returns a Worker that ignores Kill() calls. You must be sure
    60  // to call ReallyKill() to cause the worker to fail with the supplied error,
    61  // lest any goroutines trying to manage it be leaked or blocked forever.
    62  func NewForeverWorker(err error) *ForeverWorker {
    63  	w := &ForeverWorker{err: err}
    64  	go func() {
    65  		defer w.tomb.Done()
    66  		<-w.tomb.Dying()
    67  	}()
    68  	return w
    69  }
    70  
    71  // ForeverWorker is a Worker that breaks its contract. Use with care.
    72  type ForeverWorker struct {
    73  	tomb tomb.Tomb
    74  	err  error
    75  }
    76  
    77  // Kill is part of the worker.Worker interface.
    78  func (w *ForeverWorker) Kill() {}
    79  
    80  // Wait is part of the worker.Worker interface.
    81  func (w *ForeverWorker) Wait() error {
    82  	return w.tomb.Wait()
    83  }
    84  
    85  // ReallyKill does what Kill should.
    86  func (w *ForeverWorker) ReallyKill() {
    87  	w.tomb.Kill(w.err)
    88  }