1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"launchpad.net/juju-core/state/api"
10
"launchpad.net/juju-core/state/watcher"
13
// stringsWorker is the internal implementation of the Worker
14
// interface, using a StringsWatcher for handling changes.
15
type stringsWorker struct {
18
// handler is what will be called when events are triggered.
19
handler StringsWatchHandler
21
// mustErr is set to watcher.MustErr, but that panic()s, so
22
// we let the test suite override it.
23
mustErr func(watcher.Errer) error
26
// StringsWatchHandler implements the business logic triggered as part
27
// of watching a StringsWatcher.
28
type StringsWatchHandler interface {
29
// SetUp starts the handler, this should create the watcher we
30
// will be waiting on for more events. SetUp can return a Watcher
31
// even if there is an error, and strings Worker will make sure to
33
SetUp() (api.StringsWatcher, error)
35
// TearDown should cleanup any resources that are left around
38
// Handle is called when the Watcher has indicated there are
39
// changes, do whatever work is necessary to process it
40
Handle(changes []string) error
43
// NewStringsWorker starts a new worker running the business logic
44
// from the handler. The worker loop is started in another goroutine
45
// as a side effect of calling this.
46
func NewStringsWorker(handler StringsWatchHandler) Worker {
49
mustErr: watcher.MustErr,
53
sw.tomb.Kill(sw.loop())
58
// Kill the loop with no-error
59
func (sw *stringsWorker) Kill() {
63
// Wait for the looping to finish
64
func (sw *stringsWorker) Wait() error {
68
func (sw *stringsWorker) loop() error {
69
w, err := sw.handler.SetUp()
72
// We don't bother to propagate an error, because we
73
// already have an error
78
defer propagateTearDown(sw.handler, &sw.tomb)
79
defer watcher.Stop(w, &sw.tomb)
82
case <-sw.tomb.Dying():
84
case changes, ok := <-w.Changes():
88
if err := sw.handler.Handle(changes); err != nil {