Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1136)

Delta Between Two Patch Sets: state/relation.go

Issue 6864050: state: Dying unit cannot enter relation scope
Left Patch Set: Created 11 years, 3 months ago
Right Patch Set: state: Dying unit cannot enter relation scope Created 11 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « [revision details] ('k') | state/relation_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 package state 1 package state
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "labix.org/v2/mgo" 6 "labix.org/v2/mgo"
7 "labix.org/v2/mgo/bson" 7 "labix.org/v2/mgo/bson"
8 "labix.org/v2/mgo/txn" 8 "labix.org/v2/mgo/txn"
9 "launchpad.net/juju-core/charm" 9 "launchpad.net/juju-core/charm"
10 "launchpad.net/juju-core/trivial" 10 "launchpad.net/juju-core/trivial"
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 250 }
251 251
252 // ErrCannotEnterScope indicates that a relation unit failed to enter its scope 252 // ErrCannotEnterScope indicates that a relation unit failed to enter its scope
253 // due to either the unit or the relation not being Alive. 253 // due to either the unit or the relation not being Alive.
254 var ErrCannotEnterScope = errors.New("cannot enter scope: unit or relation is no t alive") 254 var ErrCannotEnterScope = errors.New("cannot enter scope: unit or relation is no t alive")
255 255
256 // EnterScope ensures that the unit has entered its scope in the relation and 256 // EnterScope ensures that the unit has entered its scope in the relation and
257 // that its relation settings contain its private address. When the unit has 257 // that its relation settings contain its private address. When the unit has
258 // already entered its relation scope, EnterScope will report success but make 258 // already entered its relation scope, EnterScope will report success but make
259 // no changes to state; otherwise, it is an error for either the relation or 259 // no changes to state; otherwise, it is an error for either the relation or
260 // the unit not to be Alive. Once a unit has entered a scope, in stays in scope 260 // the unit not to be Alive. Once a unit has entered a scope, it stays in scope
rog 2012/12/07 10:06:21 s/in stays/it stays/
fwereade 2012/12/07 15:06:11 Done.
261 // without further intervention; the relation will not be able to become Dead 261 // without further intervention; the relation will not be able to become Dead
262 // until all units have departed its scopes. 262 // until all units have departed its scopes.
263 func (ru *RelationUnit) EnterScope() error { 263 func (ru *RelationUnit) EnterScope() error {
264 key, err := ru.key(ru.unit.Name()) 264 key, err := ru.key(ru.unit.Name())
265 if err != nil { 265 if err != nil {
266 return err 266 return err
267 } 267 }
268 desc := fmt.Sprintf("unit %q in relation %q", ru.unit, ru.relation) 268 desc := fmt.Sprintf("unit %q in relation %q", ru.unit, ru.relation)
269 if count, err := ru.st.relationScopes.FindId(key).Count(); err != nil { 269 if count, err := ru.st.relationScopes.FindId(key).Count(); err != nil {
270 return fmt.Errorf("cannot examine scope for %s: %v", desc, err) 270 return fmt.Errorf("cannot examine scope for %s: %v", desc, err)
(...skipping 12 matching lines...) Expand all
283 Update: D{{"$inc", D{{"unitcount", 1}}}}, 283 Update: D{{"$inc", D{{"unitcount", 1}}}},
284 }, { 284 }, {
285 C: ru.st.units.Name, 285 C: ru.st.units.Name,
286 Id: ru.unit.Name(), 286 Id: ru.unit.Name(),
287 Assert: isAlive, 287 Assert: isAlive,
288 }} 288 }}
289 if _, err := readSettings(ru.st, key); IsNotFound(err) { 289 if _, err := readSettings(ru.st, key); IsNotFound(err) {
290 // If settings do not already exist, create them. 290 // If settings do not already exist, create them.
291 address, err := ru.unit.PrivateAddress() 291 address, err := ru.unit.PrivateAddress()
292 if err != nil { 292 if err != nil {
293 return fmt.Errorf("cannot initialize state for %s: %v", desc, err) 293 return fmt.Errorf("cannot initialize state for %s: %v", desc, err)
rog 2012/12/07 10:06:21 how is getting the private address "initializing s
fwereade 2012/12/07 10:30:04 It's not. The error is stating that it's impossibl
rog 2012/12/07 10:40:53 ah yes, i'd read the txn.DocMissing as pertaining
294 } 294 }
295 ops = append([]txn.Op{{ 295 ops = append([]txn.Op{{
296 C: ru.st.settings.Name, 296 C: ru.st.settings.Name,
297 Id: key, 297 Id: key,
298 Assert: txn.DocMissing, 298 Assert: txn.DocMissing,
299 Insert: map[string]interface{}{"private-address": addres s}, 299 Insert: map[string]interface{}{"private-address": addres s},
300 }}, ops...) 300 }}, ops...)
301 } else if err != nil { 301 } else if err != nil {
302 return fmt.Errorf("cannot check settings for %s: %v", desc, err) 302 return fmt.Errorf("cannot check settings for %s: %v", desc, err)
303 } 303 }
304 » if err := ru.st.runner.Run(ops, "", nil); err == txn.ErrAborted { 304 » if err := ru.st.runner.Run(ops, "", nil); err != txn.ErrAborted {
305 » » if count, err := ru.st.relationScopes.FindId(key).Count(); err ! = nil {
306 » » » return fmt.Errorf("cannot examine scope for %s: %v", des c, err)
307 » » } else if count != 0 {
308 » » » return nil
309 » » }
310 » » for _, l := range []lifeRefresher{ru.relation, ru.unit} {
rog 2012/12/07 10:06:21 perhaps a comment might be appropriate here, sayin
fwereade 2012/12/07 10:30:04 If any DocMissing failed, we must already be in sc
rog 2012/12/07 10:40:53 i think that something encapsulating the above inf
fwereade 2012/12/07 15:06:11 Indeed -- I wasn't trying to say "no comments!", I
311 » » » if err := l.Refresh(); IsNotFound(err) {
312 » » » » return ErrCannotEnterScope
313 » » » } else if err != nil {
314 » » » » return err
315 » » » }
316 » » » if l.Life() != Alive {
317 » » » » return ErrCannotEnterScope
318 » » » }
jameinel 2012/12/04 09:06:08 This feels like something that would like to retur
fwereade 2012/12/04 11:31:45 Please expand... what is improved by emitting/hand
TheMue 2012/12/07 10:07:10 Here I have my troubles. If it is an expected and
fwereade 2012/12/07 10:30:04 I'm confused... why is this different from all the
rog 2012/12/07 10:40:53 i think returning specific errors is just fine. we
319 » » }
320 » » return fmt.Errorf("cannot enter scope for %s: inconsistent state ", desc)
321 » } else if err != nil {
322 return err 305 return err
323 } 306 }
324 » return nil 307 » if count, err := ru.st.relationScopes.FindId(key).Count(); err != nil {
308 » » return fmt.Errorf("cannot examine scope for %s: %v", desc, err)
309 » } else if count != 0 {
310 » » // The scope document exists, so we're already in scope; the txn was
311 » » // aborted by one of the DocMissing checks.
312 » » return nil
313 » }
314 » // If there's no scope document, the abort should be a consequence of
315 » // one of the isAlive checks: find out which.
316 » for _, l := range []lifeRefresher{ru.relation, ru.unit} {
317 » » if err := l.Refresh(); IsNotFound(err) {
318 » » » return ErrCannotEnterScope
319 » » } else if err != nil {
320 » » » return err
321 » » }
322 » » if l.Life() != Alive {
323 » » » return ErrCannotEnterScope
324 » » }
325 » }
326 » // Apparently, all our assertions should have passed, but the txn was
327 » // aborted: something is badly wrong.
328 » return fmt.Errorf("cannot enter scope for %s: inconsistent state", desc)
325 } 329 }
326 330
327 type lifeRefresher interface { 331 type lifeRefresher interface {
328 Life() Life 332 Life() Life
329 Refresh() error 333 Refresh() error
330 } 334 }
331 335
332 // LeaveScope signals that the unit has left its scope in the relation. 336 // LeaveScope signals that the unit has left its scope in the relation.
333 // After the unit has left its relation scope, it is no longer a member 337 // After the unit has left its relation scope, it is no longer a member
334 // of the relation; if the relation is dying when its last member unit 338 // of the relation; if the relation is dying when its last member unit
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 // relationScopeDoc represents a unit which is in a relation scope. 470 // relationScopeDoc represents a unit which is in a relation scope.
467 // The relation, container, role, and unit are all encoded in the key. 471 // The relation, container, role, and unit are all encoded in the key.
468 type relationScopeDoc struct { 472 type relationScopeDoc struct {
469 Key string `bson:"_id"` 473 Key string `bson:"_id"`
470 } 474 }
471 475
472 func (d *relationScopeDoc) unitName() string { 476 func (d *relationScopeDoc) unitName() string {
473 parts := strings.Split(d.Key, "#") 477 parts := strings.Split(d.Key, "#")
474 return parts[len(parts)-1] 478 return parts[len(parts)-1]
475 } 479 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b