LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package state | 4 package state |
5 | 5 |
6 import ( | 6 import ( |
7 stderrors "errors" | 7 stderrors "errors" |
8 "fmt" | 8 "fmt" |
9 "labix.org/v2/mgo" | 9 "labix.org/v2/mgo" |
10 "labix.org/v2/mgo/txn" | 10 "labix.org/v2/mgo/txn" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return err | 73 return err |
74 } | 74 } |
75 if count, err := ru.st.relationScopes.FindId(ruKey).Count(); err != nil
{ | 75 if count, err := ru.st.relationScopes.FindId(ruKey).Count(); err != nil
{ |
76 return err | 76 return err |
77 } else if count != 0 { | 77 } else if count != 0 { |
78 return nil | 78 return nil |
79 } | 79 } |
80 | 80 |
81 // Collect the operations necessary to enter scope, as follows: | 81 // Collect the operations necessary to enter scope, as follows: |
82 // * Check unit and relation state, and incref the relation. | 82 // * Check unit and relation state, and incref the relation. |
| 83 // * TODO(fwereade): check unit status == params.StatusStarted (this |
| 84 // breaks a bunch of tests in a boring but noisy-to-fix way, and is |
| 85 // being saved for a followup). |
83 unitName, relationKey := ru.unit.doc.Name, ru.relation.doc.Key | 86 unitName, relationKey := ru.unit.doc.Name, ru.relation.doc.Key |
84 ops := []txn.Op{{ | 87 ops := []txn.Op{{ |
85 C: ru.st.units.Name, | 88 C: ru.st.units.Name, |
86 Id: unitName, | 89 Id: unitName, |
87 Assert: isAliveDoc, | 90 Assert: isAliveDoc, |
88 }, { | 91 }, { |
89 C: ru.st.relations.Name, | 92 C: ru.st.relations.Name, |
90 Id: relationKey, | 93 Id: relationKey, |
91 Assert: isAliveDoc, | 94 Assert: isAliveDoc, |
92 Update: D{{"$inc", D{{"unitcount", 1}}}}, | 95 Update: D{{"$inc", D{{"unitcount", 1}}}}, |
(...skipping 28 matching lines...) Expand all Loading... |
121 // * If the unit should have a subordinate, and does not, create it. | 124 // * If the unit should have a subordinate, and does not, create it. |
122 var existingSubName string | 125 var existingSubName string |
123 if subOps, subName, err := ru.subordinateOps(); err != nil { | 126 if subOps, subName, err := ru.subordinateOps(); err != nil { |
124 return err | 127 return err |
125 } else { | 128 } else { |
126 existingSubName = subName | 129 existingSubName = subName |
127 ops = append(ops, subOps...) | 130 ops = append(ops, subOps...) |
128 } | 131 } |
129 | 132 |
130 // Now run the complete transaction, or figure out why we can't. | 133 // Now run the complete transaction, or figure out why we can't. |
131 » if err := ru.st.runner.Run(ops, "", nil); err != txn.ErrAborted { | 134 » if err := ru.st.runTransaction(ops); err != txn.ErrAborted { |
132 return err | 135 return err |
133 } | 136 } |
134 if count, err := ru.st.relationScopes.FindId(ruKey).Count(); err != nil
{ | 137 if count, err := ru.st.relationScopes.FindId(ruKey).Count(); err != nil
{ |
135 return err | 138 return err |
136 } else if count != 0 { | 139 } else if count != 0 { |
137 // The scope document exists, so we're actually already in scope
. | 140 // The scope document exists, so we're actually already in scope
. |
138 return nil | 141 return nil |
139 } | 142 } |
140 | 143 |
141 // The relation or unit might no longer be Alive. (Note that there is no | 144 // The relation or unit might no longer be Alive. (Note that there is no |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 Assert: D{{"unitcount", D{{"$gt", 1}}}}, | 280 Assert: D{{"unitcount", D{{"$gt", 1}}}}, |
278 Update: D{{"$inc", D{{"unitcount", -1}}}}, | 281 Update: D{{"$inc", D{{"unitcount", -1}}}}, |
279 }) | 282 }) |
280 } else { | 283 } else { |
281 relOps, err := ru.relation.removeOps("", ru.unit) | 284 relOps, err := ru.relation.removeOps("", ru.unit) |
282 if err != nil { | 285 if err != nil { |
283 return err | 286 return err |
284 } | 287 } |
285 ops = append(ops, relOps...) | 288 ops = append(ops, relOps...) |
286 } | 289 } |
287 » » if err = ru.st.runner.Run(ops, "", nil); err != txn.ErrAborted { | 290 » » if err = ru.st.runTransaction(ops); err != txn.ErrAborted { |
288 if err != nil { | 291 if err != nil { |
289 return fmt.Errorf("cannot leave scope for %s: %v
", desc, err) | 292 return fmt.Errorf("cannot leave scope for %s: %v
", desc, err) |
290 } | 293 } |
291 return err | 294 return err |
292 } | 295 } |
293 if err := ru.relation.Refresh(); errors.IsNotFoundError(err) { | 296 if err := ru.relation.Refresh(); errors.IsNotFoundError(err) { |
294 return nil | 297 return nil |
295 } else if err != nil { | 298 } else if err != nil { |
296 return err | 299 return err |
297 } | 300 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 // relationScopeDoc represents a unit which is in a relation scope. | 360 // relationScopeDoc represents a unit which is in a relation scope. |
358 // The relation, container, role, and unit are all encoded in the key. | 361 // The relation, container, role, and unit are all encoded in the key. |
359 type relationScopeDoc struct { | 362 type relationScopeDoc struct { |
360 Key string `bson:"_id"` | 363 Key string `bson:"_id"` |
361 } | 364 } |
362 | 365 |
363 func (d *relationScopeDoc) unitName() string { | 366 func (d *relationScopeDoc) unitName() string { |
364 parts := strings.Split(d.Key, "#") | 367 parts := strings.Split(d.Key, "#") |
365 return parts[len(parts)-1] | 368 return parts[len(parts)-1] |
366 } | 369 } |
LEFT | RIGHT |