github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/watcher/interface.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package watcher
     5  
     6  import (
     7  	"gopkg.in/juju/worker.v1"
     8  )
     9  
    10  // CoreWatcher encodes some features of a watcher. The most obvious one:
    11  //
    12  //     Changes() <-chan <T>
    13  //
    14  // ...can't be expressed cleanly; and this is annoying because every such chan
    15  // needs to share common behaviours for the abstraction to be generally helpful.
    16  // The critical features of a Changes chan are as follows:
    17  //
    18  //    * The channel should never be closed.
    19  //    * The channel should send a single baseline value, representing the change
    20  //      from a nil state; and subsequently send values representing deltas from
    21  //      whatever had previously been sent.
    22  //    * The channel should really never be closed. Many existing watchers *do*
    23  //      close their channels when the watcher stops; this is harmful because it
    24  //      mixes lifetime-handling into change-handling at the cost of clarity (and
    25  //      in some cases correctness). So long as a watcher implements Worker, it
    26  //      can be safely managed with the worker/catacomb package; of course, all
    27  //      sensible clients will still check for closed channels (never trust a
    28  //      contract...) but can treat that scenario as a simple error.
    29  //
    30  // To convert a state/watcher.Watcher to a CoreWatcher, ensure that the watcher
    31  // no longer closes its Changes() channel; and replace Stop() and Err() with the
    32  // usual worker boilerplate. Namely:
    33  //
    34  //      // Kill is part of the worker.Worker interface.
    35  //      func (w *watcher) Kill() {
    36  //          w.tomb.Kill(nil)
    37  //      }
    38  //
    39  //      // Wait is part of the worker.Worker interface.
    40  //      func (w *watcher) Wait() error {
    41  //          return w.tomb.Wait()
    42  //      }
    43  //
    44  // Tests using state/testing/{$Kind}WatcherC should be converted to use the
    45  // equivalents in watcher/watchertest.
    46  type CoreWatcher interface {
    47  	worker.Worker
    48  }