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

Side by Side Diff: state/minimumunits.go

Issue 11003044: Implemented service.EnsureMinUnits().
Patch Set: Implemented service.EnsureMinUnits(). Created 11 years, 9 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:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012, 2013 Canonical Ltd. 1 // Copyright 2012, 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 "errors" 7 "errors"
8 8
9 "labix.org/v2/mgo/txn" 9 "labix.org/v2/mgo/txn"
10 10
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 C: st.minUnits.Name, 115 C: st.minUnits.Name,
116 Id: serviceName, 116 Id: serviceName,
117 Remove: true, 117 Remove: true,
118 } 118 }
119 } 119 }
120 120
121 // MinUnits returns the minimum units count for the service. 121 // MinUnits returns the minimum units count for the service.
122 func (s *Service) MinUnits() int { 122 func (s *Service) MinUnits() int {
123 return s.doc.MinUnits 123 return s.doc.MinUnits
124 } 124 }
125
126 // EnsureMinUnits adds new units if the service's MinUnits value is greater
127 // than the number of alive units.
128 func (s *Service) EnsureMinUnits() (err error) {
129 defer utils.ErrorContextf(&err,
dimitern 2013/07/11 20:05:12 please, either put the whole statement on one line
frankban 2013/07/12 10:07:22 I'd be happier to do this after understanding the
dimitern 2013/07/15 11:28:24 Sorry, probably personal preference and also makes
130 "cannot ensure minimum units for service %q", s)
131 service := &Service{st: s.st, doc: s.doc}
132 for {
133 // Ensure the service is alive.
134 if service.doc.Life != Alive {
dimitern 2013/07/11 20:05:12 this should be an transaction assert op, rather th
frankban 2013/07/12 10:07:22 The assertion is already included in the transacti
fwereade 2013/07/15 11:02:53 +1 to frankban. It's annoying that we have to defi
dimitern 2013/07/15 11:28:24 OK, good point objection withdrawn.
135 return errors.New("service is no longer alive")
136 }
137 // Exit without errors if the MinUnits for the service is not se t.
138 if service.doc.MinUnits == 0 {
dimitern 2013/07/11 20:05:12 ditto
frankban 2013/07/12 10:07:22 See the comment above.
139 return nil
140 }
141 // Retrieve the number of alive units for the service.
142 aliveUnits, err := aliveUnitsCount(service)
dimitern 2013/07/11 20:05:12 ditto
frankban 2013/07/12 10:07:22 See the comment above.
143 if err != nil {
144 return err
145 }
146 // Calculate the number of required units to be added.
147 missing := service.doc.MinUnits - aliveUnits
dimitern 2013/07/11 20:05:12 ditto
frankban 2013/07/12 10:07:22 See the comment above.
148 if missing <= 0 {
149 return nil
150 }
151 name, ops, err := ensureMinUnitsOps(service)
152 if err != nil {
153 return err
154 }
155 // Add missing unit.
156 switch err := s.st.runTransaction(ops); err {
157 case nil:
158 // Assign the new unit.
159 unit, err := service.Unit(name)
160 if err != nil {
161 return err
162 }
163 if err := service.st.AssignUnit(unit, AssignNew); err != nil {
164 return err
165 }
166 // No need to proceed and refresh the service if this wa s the
167 // last/only missing unit.
168 if missing == 1 {
169 return nil
170 }
171 case txn.ErrAborted:
172 default:
173 return err
dimitern 2013/07/11 20:05:12 I don't think this is right - the transaction can
frankban 2013/07/12 10:07:22 If I read this lines correctly, this is exactly wh
fwereade 2013/07/15 11:02:53 frankban's right, but I agree that a casual readin
dimitern 2013/07/15 11:28:24 Sorry, I read it incorrectly (that's why you shoul
174 }
175 if err := service.Refresh(); err != nil {
176 return err
177 }
178 }
179 panic("unreachable")
180 }
181
182 // aliveUnitsCount returns the number a alive units for the service.
183 func aliveUnitsCount(service *Service) (int, error) {
184 query := D{{"service", service.doc.Name}, {"life", Alive}}
dimitern 2013/07/11 20:05:12 this needs to be an assert op, take a look at serv
frankban 2013/07/12 10:07:22 Could you please be more specific? Why do I need a
fwereade 2013/07/15 11:02:53 I don't think you do, but I'm interested to hear d
dimitern 2013/07/15 11:28:24 See the above comment and just ignore me, sorry :/
185 return service.st.units.Find(query).Count()
186 }
187
188 // ensureMinUnitsOps returns the operations required to add a unit for the
189 // service in MongoDB and the name for the new unit. The resulting transaction
190 // will be aborted if the service document changes when running the operations.
191 func ensureMinUnitsOps(service *Service) (string, []txn.Op, error) {
192 asserts := D{{"txn-revno", service.doc.TxnRevno}}
193 return service.addUnitOps("", asserts)
194 }
OLDNEW

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