OLD | NEW |
1 package uniter | 1 package uniter |
2 | 2 |
3 import ( | 3 import ( |
4 "fmt" | 4 "fmt" |
5 "launchpad.net/juju-core/charm" | 5 "launchpad.net/juju-core/charm" |
6 "launchpad.net/juju-core/log" | 6 "launchpad.net/juju-core/log" |
7 "launchpad.net/juju-core/state" | 7 "launchpad.net/juju-core/state" |
8 "launchpad.net/juju-core/state/api/params" | |
9 "launchpad.net/juju-core/state/watcher" | 8 "launchpad.net/juju-core/state/watcher" |
10 "launchpad.net/juju-core/worker" | 9 "launchpad.net/juju-core/worker" |
11 "launchpad.net/tomb" | 10 "launchpad.net/tomb" |
12 "sort" | 11 "sort" |
13 ) | 12 ) |
14 | 13 |
15 // filter collects unit, service, and service config information from separate | 14 // filter collects unit, service, and service config information from separate |
16 // state watchers, and presents it as events on channels designed specifically | 15 // state watchers, and presents it as events on channels designed specifically |
17 // for the convenience of the uniter. | 16 // for the convenience of the uniter. |
18 type filter struct { | 17 type filter struct { |
19 st *state.State | 18 st *state.State |
20 tomb tomb.Tomb | 19 tomb tomb.Tomb |
21 | 20 |
22 // outUnitDying is closed when the unit's life becomes Dying. | 21 // outUnitDying is closed when the unit's life becomes Dying. |
23 outUnitDying chan struct{} | 22 outUnitDying chan struct{} |
24 | 23 |
25 // The out*On chans are used to deliver events to clients. | 24 // The out*On chans are used to deliver events to clients. |
26 // The out* chans, when set to the corresponding out*On chan (rather tha
n | 25 // The out* chans, when set to the corresponding out*On chan (rather tha
n |
27 // nil) indicate that an event of the appropriate type is ready to send | 26 // nil) indicate that an event of the appropriate type is ready to send |
28 // to the client. | 27 // to the client. |
29 outConfig chan struct{} | 28 outConfig chan struct{} |
30 outConfigOn chan struct{} | 29 outConfigOn chan struct{} |
31 outUpgrade chan *charm.URL | 30 outUpgrade chan *charm.URL |
32 outUpgradeOn chan *charm.URL | 31 outUpgradeOn chan *charm.URL |
33 » outResolved chan params.ResolvedMode | 32 » outResolved chan state.ResolvedMode |
34 » outResolvedOn chan params.ResolvedMode | 33 » outResolvedOn chan state.ResolvedMode |
35 outRelations chan []int | 34 outRelations chan []int |
36 outRelationsOn chan []int | 35 outRelationsOn chan []int |
37 | 36 |
38 // The want* chans are used to indicate that the filter should send | 37 // The want* chans are used to indicate that the filter should send |
39 // events if it has them available. | 38 // events if it has them available. |
40 wantForcedUpgrade chan bool | 39 wantForcedUpgrade chan bool |
41 wantResolved chan struct{} | 40 wantResolved chan struct{} |
42 | 41 |
43 // discardConfig is used to indicate that any pending config event | 42 // discardConfig is used to indicate that any pending config event |
44 // should be discarded. | 43 // should be discarded. |
45 discardConfig chan struct{} | 44 discardConfig chan struct{} |
46 | 45 |
47 // setCharm is used to request that the unit's charm URL be set to | 46 // setCharm is used to request that the unit's charm URL be set to |
48 // a new value. This must be done in the filter's goroutine, so | 47 // a new value. This must be done in the filter's goroutine, so |
49 // that config watches can be stopped and restarted pointing to | 48 // that config watches can be stopped and restarted pointing to |
50 // the new charm URL. If we don't stop the watch before the | 49 // the new charm URL. If we don't stop the watch before the |
51 // (potentially) last reference to that settings document is | 50 // (potentially) last reference to that settings document is |
52 // removed, we'll see spurious errors (and even in the best case, | 51 // removed, we'll see spurious errors (and even in the best case, |
53 // we risk getting notifications for the wrong settings version). | 52 // we risk getting notifications for the wrong settings version). |
54 setCharm chan *charm.URL | 53 setCharm chan *charm.URL |
55 | 54 |
56 // charmChanged is used to report back after setting a charm URL. | 55 // charmChanged is used to report back after setting a charm URL. |
57 charmChanged chan struct{} | 56 charmChanged chan struct{} |
58 | 57 |
59 // The following fields hold state that is collected while running, | 58 // The following fields hold state that is collected while running, |
60 // and used to detect interesting changes to express as events. | 59 // and used to detect interesting changes to express as events. |
61 unit *state.Unit | 60 unit *state.Unit |
62 life state.Life | 61 life state.Life |
63 » resolved params.ResolvedMode | 62 » resolved state.ResolvedMode |
64 service *state.Service | 63 service *state.Service |
65 upgradeFrom serviceCharm | 64 upgradeFrom serviceCharm |
66 upgradeAvailable serviceCharm | 65 upgradeAvailable serviceCharm |
67 upgrade *charm.URL | 66 upgrade *charm.URL |
68 relations []int | 67 relations []int |
69 } | 68 } |
70 | 69 |
71 // newFilter returns a filter that handles state changes pertaining to the | 70 // newFilter returns a filter that handles state changes pertaining to the |
72 // supplied unit. | 71 // supplied unit. |
73 func newFilter(st *state.State, unitName string) (*filter, error) { | 72 func newFilter(st *state.State, unitName string) (*filter, error) { |
74 f := &filter{ | 73 f := &filter{ |
75 st: st, | 74 st: st, |
76 outUnitDying: make(chan struct{}), | 75 outUnitDying: make(chan struct{}), |
77 outConfig: make(chan struct{}), | 76 outConfig: make(chan struct{}), |
78 outConfigOn: make(chan struct{}), | 77 outConfigOn: make(chan struct{}), |
79 outUpgrade: make(chan *charm.URL), | 78 outUpgrade: make(chan *charm.URL), |
80 outUpgradeOn: make(chan *charm.URL), | 79 outUpgradeOn: make(chan *charm.URL), |
81 » » outResolved: make(chan params.ResolvedMode), | 80 » » outResolved: make(chan state.ResolvedMode), |
82 » » outResolvedOn: make(chan params.ResolvedMode), | 81 » » outResolvedOn: make(chan state.ResolvedMode), |
83 outRelations: make(chan []int), | 82 outRelations: make(chan []int), |
84 outRelationsOn: make(chan []int), | 83 outRelationsOn: make(chan []int), |
85 wantForcedUpgrade: make(chan bool), | 84 wantForcedUpgrade: make(chan bool), |
86 wantResolved: make(chan struct{}), | 85 wantResolved: make(chan struct{}), |
87 discardConfig: make(chan struct{}), | 86 discardConfig: make(chan struct{}), |
88 setCharm: make(chan *charm.URL), | 87 setCharm: make(chan *charm.URL), |
89 charmChanged: make(chan struct{}), | 88 charmChanged: make(chan struct{}), |
90 } | 89 } |
91 go func() { | 90 go func() { |
92 defer f.tomb.Done() | 91 defer f.tomb.Done() |
(...skipping 26 matching lines...) Expand all Loading... |
119 // upgrade is indicated. Events should not be read until the baseline state | 118 // upgrade is indicated. Events should not be read until the baseline state |
120 // has been specified by calling WantUpgradeEvent. | 119 // has been specified by calling WantUpgradeEvent. |
121 func (f *filter) UpgradeEvents() <-chan *charm.URL { | 120 func (f *filter) UpgradeEvents() <-chan *charm.URL { |
122 return f.outUpgradeOn | 121 return f.outUpgradeOn |
123 } | 122 } |
124 | 123 |
125 // ResolvedEvents returns a channel that may receive a ResolvedMode when the | 124 // ResolvedEvents returns a channel that may receive a ResolvedMode when the |
126 // unit's Resolved value changes, or when an event is explicitly requested. | 125 // unit's Resolved value changes, or when an event is explicitly requested. |
127 // A ResolvedNone state will never generate events, but ResolvedRetryHooks and | 126 // A ResolvedNone state will never generate events, but ResolvedRetryHooks and |
128 // ResolvedNoHooks will always be delivered as described. | 127 // ResolvedNoHooks will always be delivered as described. |
129 func (f *filter) ResolvedEvents() <-chan params.ResolvedMode { | 128 func (f *filter) ResolvedEvents() <-chan state.ResolvedMode { |
130 return f.outResolvedOn | 129 return f.outResolvedOn |
131 } | 130 } |
132 | 131 |
133 // ConfigEvents returns a channel that will receive a signal whenever the servic
e's | 132 // ConfigEvents returns a channel that will receive a signal whenever the servic
e's |
134 // configuration changes, or when an event is explicitly requested. | 133 // configuration changes, or when an event is explicitly requested. |
135 func (f *filter) ConfigEvents() <-chan struct{} { | 134 func (f *filter) ConfigEvents() <-chan struct{} { |
136 return f.outConfigOn | 135 return f.outConfigOn |
137 } | 136 } |
138 | 137 |
139 // RelationsEvents returns a channel that will receive the ids of all the servic
e's | 138 // RelationsEvents returns a channel that will receive the ids of all the servic
e's |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 return err | 330 return err |
332 } | 331 } |
333 case force := <-f.wantForcedUpgrade: | 332 case force := <-f.wantForcedUpgrade: |
334 log.Debugf("worker/uniter/filter: want forced upgrade %v
", force) | 333 log.Debugf("worker/uniter/filter: want forced upgrade %v
", force) |
335 f.upgradeFrom.force = force | 334 f.upgradeFrom.force = force |
336 if err = f.upgradeChanged(); err != nil { | 335 if err = f.upgradeChanged(); err != nil { |
337 return err | 336 return err |
338 } | 337 } |
339 case <-f.wantResolved: | 338 case <-f.wantResolved: |
340 log.Debugf("worker/uniter/filter: want resolved event") | 339 log.Debugf("worker/uniter/filter: want resolved event") |
341 » » » if f.resolved != params.ResolvedNone { | 340 » » » if f.resolved != state.ResolvedNone { |
342 f.outResolved = f.outResolvedOn | 341 f.outResolved = f.outResolvedOn |
343 } | 342 } |
344 case <-discardConfig: | 343 case <-discardConfig: |
345 log.Debugf("worker/uniter/filter: discarded config event
") | 344 log.Debugf("worker/uniter/filter: discarded config event
") |
346 f.outConfig = nil | 345 f.outConfig = nil |
347 } | 346 } |
348 } | 347 } |
349 panic("unreachable") | 348 panic("unreachable") |
350 } | 349 } |
351 | 350 |
(...skipping 11 matching lines...) Expand all Loading... |
363 log.Noticef("worker/uniter/filter: unit is dying") | 362 log.Noticef("worker/uniter/filter: unit is dying") |
364 close(f.outUnitDying) | 363 close(f.outUnitDying) |
365 f.outUpgrade = nil | 364 f.outUpgrade = nil |
366 case state.Dead: | 365 case state.Dead: |
367 log.Noticef("worker/uniter/filter: unit is dead") | 366 log.Noticef("worker/uniter/filter: unit is dead") |
368 return worker.ErrTerminateAgent | 367 return worker.ErrTerminateAgent |
369 } | 368 } |
370 } | 369 } |
371 if resolved := f.unit.Resolved(); resolved != f.resolved { | 370 if resolved := f.unit.Resolved(); resolved != f.resolved { |
372 f.resolved = resolved | 371 f.resolved = resolved |
373 » » if f.resolved != params.ResolvedNone { | 372 » » if f.resolved != state.ResolvedNone { |
374 f.outResolved = f.outResolvedOn | 373 f.outResolved = f.outResolvedOn |
375 } | 374 } |
376 } | 375 } |
377 return nil | 376 return nil |
378 } | 377 } |
379 | 378 |
380 // serviceChanged responds to changes in the service. | 379 // serviceChanged responds to changes in the service. |
381 func (f *filter) serviceChanged() error { | 380 func (f *filter) serviceChanged() error { |
382 if err := f.service.Refresh(); err != nil { | 381 if err := f.service.Refresh(); err != nil { |
383 if state.IsNotFound(err) { | 382 if state.IsNotFound(err) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 } | 444 } |
446 | 445 |
447 // serviceCharm holds information about a charm. | 446 // serviceCharm holds information about a charm. |
448 type serviceCharm struct { | 447 type serviceCharm struct { |
449 url *charm.URL | 448 url *charm.URL |
450 force bool | 449 force bool |
451 } | 450 } |
452 | 451 |
453 // nothing is marginally more pleasant to read than "struct{}{}". | 452 // nothing is marginally more pleasant to read than "struct{}{}". |
454 var nothing = struct{}{} | 453 var nothing = struct{}{} |
OLD | NEW |