Merge lp:~chipaca/ubuntu-push/actual-client-v0 into lp:ubuntu-push
- actual-client-v0
- Merge into trunk
Proposed by
John Lenton
Status: | Rejected |
---|---|
Rejected by: | John Lenton |
Proposed branch: | lp:~chipaca/ubuntu-push/actual-client-v0 |
Merge into: | lp:ubuntu-push |
Prerequisite: | lp:~chipaca/ubuntu-push/client-v0 |
Diff against target: |
528 lines (+199/-43) 7 files modified
bus/connectivity/connectivity.go (+7/-7) bus/connectivity/connectivity_test.go (+6/-6) client.json (+9/-0) client/client.go (+141/-0) client/session/session.go (+2/-2) client/session/session_test.go (+22/-22) util/redialer.go (+12/-6) |
To merge this branch: | bzr merge lp:~chipaca/ubuntu-push/actual-client-v0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Push Hackers | Pending | ||
Review via email:
|
Commit message
v0 of the actual client. Not covered by tests yet.
Description of the change
v0 of the actual client. Not covered by tests yet.
To post a comment you must log in.
- 28. By John Lenton
-
moved client config to etc
- 29. By John Lenton
-
merged pipeline; conflict in the redialer fixed
- 30. By John Lenton
-
merged trunk, resolved conflict in redialer
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Samuele Pedroni (pedronis) wrote : | # |
Unmerged revisions
- 30. By John Lenton
-
merged trunk, resolved conflict in redialer
- 29. By John Lenton
-
merged pipeline; conflict in the redialer fixed
- 28. By John Lenton
-
moved client config to etc
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bus/connectivity/connectivity.go' |
2 | --- bus/connectivity/connectivity.go 2014-01-23 14:33:08 +0000 |
3 | +++ bus/connectivity/connectivity.go 2014-01-27 18:11:05 +0000 |
4 | @@ -34,21 +34,21 @@ |
5 | |
6 | // the configuration for ConnectedState, with the idea that you'd populate it |
7 | // from a config file. |
8 | -type Config struct { |
9 | +type ConnectivityConfig struct { |
10 | // how long to wait after a state change to make sure it's "stable" |
11 | // before acting on it |
12 | - StabilizingTimeout config.ConfigTimeDuration |
13 | + StabilizingTimeout config.ConfigTimeDuration `json:"stabilizing_timeout"` |
14 | // How long to wait between online connectivity checks. |
15 | - RecheckTimeout config.ConfigTimeDuration |
16 | + RecheckTimeout config.ConfigTimeDuration `json:"recheck_timeout"` |
17 | // The URL against which to do the connectivity check. |
18 | - ConnectivityCheckURL string |
19 | + ConnectivityCheckURL string `json:"connectivity_check_url"` |
20 | // The expected MD5 of the content at the ConnectivityCheckURL |
21 | - ConnectivityCheckMD5 string |
22 | + ConnectivityCheckMD5 string `json:"connectivity_check_md5"` |
23 | } |
24 | |
25 | type connectedState struct { |
26 | networkStateCh <-chan networkmanager.State |
27 | - config Config |
28 | + config ConnectivityConfig |
29 | log logger.Logger |
30 | endp bus.Endpoint |
31 | connAttempts uint32 |
32 | @@ -140,7 +140,7 @@ |
33 | // |
34 | // The endpoint need not be dialed; connectivity will Dial() and Close() |
35 | // it as it sees fit. |
36 | -func ConnectedState(endp bus.Endpoint, config Config, log logger.Logger, out chan<- bool) { |
37 | +func ConnectedState(endp bus.Endpoint, config ConnectivityConfig, log logger.Logger, out chan<- bool) { |
38 | wg := NewWebchecker(config.ConnectivityCheckURL, config.ConnectivityCheckMD5, log) |
39 | cs := &connectedState{ |
40 | config: config, |
41 | |
42 | === modified file 'bus/connectivity/connectivity_test.go' |
43 | --- bus/connectivity/connectivity_test.go 2014-01-24 14:12:22 +0000 |
44 | +++ bus/connectivity/connectivity_test.go 2014-01-27 18:11:05 +0000 |
45 | @@ -58,7 +58,7 @@ |
46 | // when given a working config and bus, Start() will work |
47 | func (s *ConnSuite) TestStartWorks(c *C) { |
48 | endp := testingbus.NewTestingEndpoint(condition.Work(true), condition.Work(true), uint32(networkmanager.Connecting)) |
49 | - cs := connectedState{config: Config{}, log: nullog, endp: endp} |
50 | + cs := connectedState{config: ConnectivityConfig{}, log: nullog, endp: endp} |
51 | |
52 | c.Check(cs.start(), Equals, networkmanager.Connecting) |
53 | } |
54 | @@ -66,7 +66,7 @@ |
55 | // if the bus fails a couple of times, we're still OK |
56 | func (s *ConnSuite) TestStartRetriesConnect(c *C) { |
57 | endp := testingbus.NewTestingEndpoint(condition.Fail2Work(2), condition.Work(true), uint32(networkmanager.Connecting)) |
58 | - cs := connectedState{config: Config{}, log: nullog, endp: endp} |
59 | + cs := connectedState{config: ConnectivityConfig{}, log: nullog, endp: endp} |
60 | |
61 | c.Check(cs.start(), Equals, networkmanager.Connecting) |
62 | c.Check(cs.connAttempts, Equals, uint32(3)) // 1 more than the Fail2Work |
63 | @@ -75,7 +75,7 @@ |
64 | // when the calls to NetworkManager fail for a bit, we're still OK |
65 | func (s *ConnSuite) TestStartRetriesCall(c *C) { |
66 | endp := testingbus.NewTestingEndpoint(condition.Work(true), condition.Fail2Work(5), uint32(networkmanager.Connecting)) |
67 | - cs := connectedState{config: Config{}, log: nullog, endp: endp} |
68 | + cs := connectedState{config: ConnectivityConfig{}, log: nullog, endp: endp} |
69 | |
70 | c.Check(cs.start(), Equals, networkmanager.Connecting) |
71 | |
72 | @@ -93,7 +93,7 @@ |
73 | endp := testingbus.NewTestingEndpoint(condition.Work(true), nmcond, |
74 | uint32(networkmanager.Connecting), |
75 | uint32(networkmanager.ConnectedGlobal)) |
76 | - cs := connectedState{config: Config{}, log: nullog, endp: endp} |
77 | + cs := connectedState{config: ConnectivityConfig{}, log: nullog, endp: endp} |
78 | |
79 | c.Check(cs.start(), Equals, networkmanager.Connecting) |
80 | c.Check(cs.connAttempts, Equals, uint32(2)) |
81 | @@ -109,7 +109,7 @@ |
82 | var webget_p condition.Interface = condition.Work(true) |
83 | recheck_timeout := 50 * time.Millisecond |
84 | |
85 | - cfg := Config{ |
86 | + cfg := ConnectivityConfig{ |
87 | RecheckTimeout: config.ConfigTimeDuration{recheck_timeout}, |
88 | } |
89 | ch := make(chan networkmanager.State, 10) |
90 | @@ -184,7 +184,7 @@ |
91 | ts := httptest.NewServer(mkHandler(staticText)) |
92 | defer ts.Close() |
93 | |
94 | - cfg := Config{ |
95 | + cfg := ConnectivityConfig{ |
96 | ConnectivityCheckURL: ts.URL, |
97 | ConnectivityCheckMD5: staticHash, |
98 | RecheckTimeout: config.ConfigTimeDuration{time.Second}, |
99 | |
100 | === added file 'client.json' |
101 | --- client.json 1970-01-01 00:00:00 +0000 |
102 | +++ client.json 2014-01-27 18:11:05 +0000 |
103 | @@ -0,0 +1,9 @@ |
104 | +{ |
105 | + "exchange_timeout": "30s", |
106 | + "addr": ":9090", |
107 | + "cert_pem_file": "server/acceptance/config/testing.cert", |
108 | + "stabilizing_timeout": "2s", |
109 | + "recheck_timeout": "10m", |
110 | + "connectivity_check_url": "http://start.ubuntu.com/connectivity-check.html", |
111 | + "connectivity_check_md5": "4589f42e1546aa47ca181e5d949d310b" |
112 | +} |
113 | |
114 | === added file 'client/client.go' |
115 | --- client/client.go 1970-01-01 00:00:00 +0000 |
116 | +++ client/client.go 2014-01-27 18:11:05 +0000 |
117 | @@ -0,0 +1,141 @@ |
118 | +package main |
119 | + |
120 | +import ( |
121 | + "launchpad.net/go-dbus/v1" |
122 | + "launchpad.net/ubuntu-push/bus" |
123 | + "launchpad.net/ubuntu-push/bus/connectivity" |
124 | + "launchpad.net/ubuntu-push/bus/networkmanager" |
125 | + "launchpad.net/ubuntu-push/bus/notifications" |
126 | + "launchpad.net/ubuntu-push/bus/urldispatcher" |
127 | + "launchpad.net/ubuntu-push/client/session" |
128 | + "launchpad.net/ubuntu-push/config" |
129 | + "launchpad.net/ubuntu-push/logger" |
130 | + "launchpad.net/ubuntu-push/util" |
131 | + "launchpad.net/ubuntu-push/whoopsie/identifier" |
132 | + "os" |
133 | +) |
134 | + |
135 | +type configuration struct { |
136 | + connectivity.ConnectivityConfig |
137 | + session.ClientConfig |
138 | +} |
139 | + |
140 | +const ( |
141 | + configFName string = "/etc/ubuntu-push/client.json" |
142 | +) |
143 | + |
144 | +func notify_update(nots *notifications.RawNotifications, log logger.Logger) { |
145 | + action_id := "my_action_id" |
146 | + a := []string{action_id, "Go get it!"} // action value not visible on the phone |
147 | + h := map[string]*dbus.Variant{"x-canonical-switch-to-application": &dbus.Variant{true}} |
148 | + not_id, err := nots.Notify( |
149 | + "ubuntu-push-client", // app name |
150 | + uint32(0), // id |
151 | + "update_manager_icon", // icon |
152 | + "There's an updated system image!", // summary |
153 | + "You've got to get it! Now! Run!", // body |
154 | + a, // actions |
155 | + h, // hints |
156 | + int32(10*1000), // timeout |
157 | + ) |
158 | + if err != nil { |
159 | + log.Fatalf("%s", err) |
160 | + } |
161 | + log.Debugf("Got notification id %d\n", not_id) |
162 | +} |
163 | + |
164 | +func main() { |
165 | + log := logger.NewSimpleLogger(os.Stderr, "debug") |
166 | + f, err := os.Open(configFName) |
167 | + if err != nil { |
168 | + log.Fatalf("reading config: %v", err) |
169 | + } |
170 | + cfg := &configuration{} |
171 | + err = config.ReadConfig(f, cfg) |
172 | + if err != nil { |
173 | + log.Fatalf("reading config: %v", err) |
174 | + } |
175 | + whopId := identifier.New() |
176 | + err = whopId.Generate() |
177 | + if err != nil { |
178 | + log.Fatalf("Generating device id: %v", err) |
179 | + } |
180 | + deviceId := whopId.String() |
181 | + log.Debugf("Connecting as device id %s", deviceId) |
182 | + session, err := session.NewSession(cfg.ClientConfig, log, deviceId) |
183 | + if err != nil { |
184 | + log.Fatalf("%s", err) |
185 | + } |
186 | + // ^^ up to this line, things that never change |
187 | + var is_connected, ok bool |
188 | + // vv from this line, things that never stay the same |
189 | + for { |
190 | + log.Debugf("Here we go!") |
191 | + is_connected = false |
192 | + connCh := make(chan bool) |
193 | + iniCh := make(chan uint32) |
194 | + |
195 | + notEndp := bus.SessionBus.Endpoint(notifications.BusAddress, log) |
196 | + urlEndp := bus.SessionBus.Endpoint(urldispatcher.BusAddress, log) |
197 | + |
198 | + go func() { iniCh <- util.AutoRetry(session.Reset) }() |
199 | + go func() { iniCh <- util.AutoRedial(notEndp) }() |
200 | + go func() { iniCh <- util.AutoRedial(urlEndp) }() |
201 | + go connectivity.ConnectedState(bus.SystemBus.Endpoint(networkmanager.BusAddress, log), cfg.ConnectivityConfig, log, connCh) |
202 | + |
203 | + <-iniCh |
204 | + <-iniCh |
205 | + <-iniCh |
206 | + nots := notifications.Raw(notEndp, log) |
207 | + urld := urldispatcher.New(urlEndp, log) |
208 | + |
209 | + actnCh, err := nots.WatchActions() |
210 | + if err != nil { |
211 | + log.Errorf("%s", err) |
212 | + continue |
213 | + } |
214 | + |
215 | + InnerLoop: |
216 | + for { |
217 | + select { |
218 | + case is_connected, ok = <-connCh: |
219 | + // handle connectivty changes |
220 | + // disconnect session if offline, reconnect if online |
221 | + if !ok { |
222 | + log.Errorf("connectivity checker crashed? restarting everything") |
223 | + break InnerLoop |
224 | + } |
225 | + // fallthrough |
226 | + // oh, silly ol' go doesn't like that. |
227 | + if is_connected { |
228 | + err = session.Reset() |
229 | + if err != nil { |
230 | + break InnerLoop |
231 | + } |
232 | + } |
233 | + case <-session.ErrCh: |
234 | + // handle session errors |
235 | + // restart if online, otherwise ignore |
236 | + if is_connected { |
237 | + err = session.Reset() |
238 | + if err != nil { |
239 | + break InnerLoop |
240 | + } |
241 | + } |
242 | + case <-session.MsgCh: |
243 | + // handle push notifications |
244 | + // pop up client notification |
245 | + // what to do does not depend on the rest |
246 | + // (... for now) |
247 | + log.Debugf("got a notification! let's pop it up.") |
248 | + notify_update(nots, log) |
249 | + case <-actnCh: |
250 | + // handle action clicks |
251 | + // launch system updates |
252 | + // what to do does not depend on the rest |
253 | + // (... for now) |
254 | + urld.DispatchURL("settings:///system/system-update") |
255 | + } |
256 | + } |
257 | + } |
258 | +} |
259 | |
260 | === modified file 'client/session/session.go' |
261 | --- client/session/session.go 2014-01-27 18:11:05 +0000 |
262 | +++ client/session/session.go 2014-01-27 18:11:05 +0000 |
263 | @@ -50,7 +50,7 @@ |
264 | |
265 | var _ LevelMap = &mapLevelMap{} |
266 | |
267 | -type Config struct { |
268 | +type ClientConfig struct { |
269 | // session configuration |
270 | ExchangeTimeout config.ConfigTimeDuration `json:"exchange_timeout"` |
271 | // server connection config |
272 | @@ -75,7 +75,7 @@ |
273 | MsgCh chan *Notification |
274 | } |
275 | |
276 | -func NewSession(config Config, log logger.Logger, deviceId string) (*ClientSession, error) { |
277 | +func NewSession(config ClientConfig, log logger.Logger, deviceId string) (*ClientSession, error) { |
278 | sess := &ClientSession{ |
279 | ExchangeTimeout: config.ExchangeTimeout.TimeDuration(), |
280 | ServerAddr: config.Addr.HostPort(), |
281 | |
282 | === modified file 'client/session/session_test.go' |
283 | --- client/session/session_test.go 2014-01-27 18:11:05 +0000 |
284 | +++ client/session/session_test.go 2014-01-27 18:11:05 +0000 |
285 | @@ -49,7 +49,7 @@ |
286 | ****************************************************************/ |
287 | |
288 | func (cs *clientSessionSuite) TestNewSessionPlainWorks(c *C) { |
289 | - cfg := Config{} |
290 | + cfg := ClientConfig{} |
291 | sess, err := NewSession(cfg, nullog, "wah") |
292 | c.Check(sess, NotNil) |
293 | c.Check(err, IsNil) |
294 | @@ -58,7 +58,7 @@ |
295 | var certfile string = helpers.SourceRelative("../../server/acceptance/config/testing.cert") |
296 | |
297 | func (cs *clientSessionSuite) TestNewSessionPEMWorks(c *C) { |
298 | - cfg := Config{CertPEMFile: certfile} |
299 | + cfg := ClientConfig{CertPEMFile: certfile} |
300 | sess, err := NewSession(cfg, nullog, "wah") |
301 | c.Check(sess, NotNil) |
302 | c.Assert(err, IsNil) |
303 | @@ -66,14 +66,14 @@ |
304 | } |
305 | |
306 | func (cs *clientSessionSuite) TestNewSessionBadPEMFilePathFails(c *C) { |
307 | - cfg := Config{CertPEMFile: "/no/such/path"} |
308 | + cfg := ClientConfig{CertPEMFile: "/no/such/path"} |
309 | sess, err := NewSession(cfg, nullog, "wah") |
310 | c.Check(sess, IsNil) |
311 | c.Check(err, NotNil) |
312 | } |
313 | |
314 | func (cs *clientSessionSuite) TestNewSessionBadPEMFileContentFails(c *C) { |
315 | - cfg := Config{CertPEMFile: "/etc/passwd"} |
316 | + cfg := ClientConfig{CertPEMFile: "/etc/passwd"} |
317 | sess, err := NewSession(cfg, nullog, "wah") |
318 | c.Check(sess, IsNil) |
319 | c.Check(err, NotNil) |
320 | @@ -214,7 +214,7 @@ |
321 | ****************************************************************/ |
322 | |
323 | func (cs *clientSessionSuite) TestRunFailsIfNilConnection(c *C) { |
324 | - sess, err := NewSession(Config{}, debuglog, "wah") |
325 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
326 | c.Assert(err, IsNil) |
327 | // not connected! |
328 | err = sess.run() |
329 | @@ -223,7 +223,7 @@ |
330 | } |
331 | |
332 | func (cs *clientSessionSuite) TestRunFailsIfNilProtocolator(c *C) { |
333 | - sess, err := NewSession(Config{}, debuglog, "wah") |
334 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
335 | c.Assert(err, IsNil) |
336 | sess.Connection = &testConn{Name: testname()} // ok, have a constructor |
337 | sess.Protocolator = nil // but no protocol, seeficare. |
338 | @@ -233,7 +233,7 @@ |
339 | } |
340 | |
341 | func (cs *clientSessionSuite) TestRunFailsIfSetDeadlineFails(c *C) { |
342 | - sess, err := NewSession(Config{}, debuglog, "wah") |
343 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
344 | c.Assert(err, IsNil) |
345 | sess.Connection = &testConn{Name: testname(), |
346 | DeadlineCondition: condition.Work(false)} // setdeadline will fail |
347 | @@ -243,7 +243,7 @@ |
348 | } |
349 | |
350 | func (cs *clientSessionSuite) TestRunFailsIfWriteFails(c *C) { |
351 | - sess, err := NewSession(Config{}, debuglog, "wah") |
352 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
353 | c.Assert(err, IsNil) |
354 | sess.Connection = &testConn{Name: testname(), |
355 | WriteCondition: condition.Work(false)} // write will fail |
356 | @@ -253,7 +253,7 @@ |
357 | } |
358 | |
359 | func (cs *clientSessionSuite) TestRunConnectMessageFails(c *C) { |
360 | - sess, err := NewSession(Config{}, debuglog, "wah") |
361 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
362 | c.Assert(err, IsNil) |
363 | sess.Connection = &testConn{Name: testname()} |
364 | errCh := make(chan error, 1) |
365 | @@ -278,7 +278,7 @@ |
366 | } |
367 | |
368 | func (cs *clientSessionSuite) TestRunConnackReadError(c *C) { |
369 | - sess, err := NewSession(Config{}, debuglog, "wah") |
370 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
371 | c.Assert(err, IsNil) |
372 | sess.Connection = &testConn{Name: testname()} |
373 | errCh := make(chan error, 1) |
374 | @@ -300,7 +300,7 @@ |
375 | } |
376 | |
377 | func (cs *clientSessionSuite) TestRunBadConnack(c *C) { |
378 | - sess, err := NewSession(Config{}, debuglog, "wah") |
379 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
380 | c.Assert(err, IsNil) |
381 | sess.Connection = &testConn{Name: testname()} |
382 | errCh := make(chan error, 1) |
383 | @@ -322,7 +322,7 @@ |
384 | } |
385 | |
386 | func (cs *clientSessionSuite) TestRunMainloopReadError(c *C) { |
387 | - sess, err := NewSession(Config{}, debuglog, "wah") |
388 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
389 | c.Assert(err, IsNil) |
390 | sess.Connection = &testConn{Name: testname()} |
391 | errCh := make(chan error, 1) |
392 | @@ -349,7 +349,7 @@ |
393 | } |
394 | |
395 | func (cs *clientSessionSuite) TestRunPongWriteError(c *C) { |
396 | - sess, err := NewSession(Config{}, debuglog, "wah") |
397 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
398 | c.Assert(err, IsNil) |
399 | sess.Connection = &testConn{Name: testname()} |
400 | errCh := make(chan error, 1) |
401 | @@ -378,7 +378,7 @@ |
402 | } |
403 | |
404 | func (cs *clientSessionSuite) TestRunPingPong(c *C) { |
405 | - sess, err := NewSession(Config{}, debuglog, "wah") |
406 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
407 | c.Assert(err, IsNil) |
408 | sess.Connection = &testConn{Name: testname()} |
409 | errCh := make(chan error, 1) |
410 | @@ -406,7 +406,7 @@ |
411 | } |
412 | |
413 | func (cs *clientSessionSuite) TestRunBadAckWrite(c *C) { |
414 | - sess, err := NewSession(Config{}, debuglog, "wah") |
415 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
416 | c.Assert(err, IsNil) |
417 | sess.Connection = &testConn{Name: testname()} |
418 | errCh := make(chan error, 1) |
419 | @@ -444,7 +444,7 @@ |
420 | } |
421 | |
422 | func (cs *clientSessionSuite) TestRunBroadcastWrongChannel(c *C) { |
423 | - sess, err := NewSession(Config{}, debuglog, "wah") |
424 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
425 | c.Assert(err, IsNil) |
426 | sess.Connection = &testConn{Name: testname()} |
427 | errCh := make(chan error, 1) |
428 | @@ -482,7 +482,7 @@ |
429 | } |
430 | |
431 | func (cs *clientSessionSuite) TestRunBroadcastRightChannel(c *C) { |
432 | - sess, err := NewSession(Config{}, debuglog, "wah") |
433 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
434 | c.Assert(err, IsNil) |
435 | sess.Connection = &testConn{Name: testname()} |
436 | sess.ErrCh = make(chan error, 1) |
437 | @@ -528,7 +528,7 @@ |
438 | */ |
439 | |
440 | func (cs *clientSessionSuite) TestDialFailsWithNoAddress(c *C) { |
441 | - sess, err := NewSession(Config{}, debuglog, "wah") |
442 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
443 | c.Assert(err, IsNil) |
444 | err = sess.Dial() |
445 | c.Assert(err, NotNil) |
446 | @@ -539,7 +539,7 @@ |
447 | lp, err := net.Listen("tcp", ":0") |
448 | c.Assert(err, IsNil) |
449 | defer lp.Close() |
450 | - sess, err := NewSession(Config{}, debuglog, "wah") |
451 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
452 | c.Assert(err, IsNil) |
453 | sess.ServerAddr = lp.Addr().String() |
454 | err = sess.Dial() |
455 | @@ -548,7 +548,7 @@ |
456 | } |
457 | |
458 | func (cs *clientSessionSuite) TestResetFailsWithoutProtocolator(c *C) { |
459 | - sess, _ := NewSession(Config{}, debuglog, "wah") |
460 | + sess, _ := NewSession(ClientConfig{}, debuglog, "wah") |
461 | sess.Protocolator = nil |
462 | err := sess.Reset() |
463 | c.Assert(err, NotNil) |
464 | @@ -556,7 +556,7 @@ |
465 | } |
466 | |
467 | func (cs *clientSessionSuite) TestResetFailsWithNoAddress(c *C) { |
468 | - sess, err := NewSession(Config{}, debuglog, "wah") |
469 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
470 | c.Assert(err, IsNil) |
471 | err = sess.Reset() |
472 | c.Assert(err, NotNil) |
473 | @@ -571,7 +571,7 @@ |
474 | c.Assert(err, IsNil) |
475 | defer lp.Close() |
476 | |
477 | - sess, err := NewSession(Config{}, debuglog, "wah") |
478 | + sess, err := NewSession(ClientConfig{}, debuglog, "wah") |
479 | c.Assert(err, IsNil) |
480 | sess.ServerAddr = lp.Addr().String() |
481 | sess.Connection = &testConn{Name: testname()} |
482 | |
483 | === modified file 'util/redialer.go' |
484 | --- util/redialer.go 2014-01-27 13:02:26 +0000 |
485 | +++ util/redialer.go 2014-01-27 18:11:05 +0000 |
486 | @@ -49,15 +49,14 @@ |
487 | return time.Duration(rand.Int63n(2*n+1) - n) |
488 | } |
489 | |
490 | -// AutoRedialer takes a Dialer and retries its Dial() method until it |
491 | -// stops returning an error. It does exponential (optionally |
492 | -// jitter'ed) backoff. |
493 | -func AutoRedial(dialer Dialer) uint32 { |
494 | +// AutoRetry keeps on calling f() until it stops returning an error. |
495 | +// It does exponential backoff, adding jitter at each step back. |
496 | +func AutoRetry(f func() error, jitter func(time.Duration) time.Duration) uint32 { |
497 | var timeout time.Duration |
498 | var dialAttempts uint32 = 0 // unsigned so it can wrap safely ... |
499 | var numTimeouts uint32 = uint32(len(Timeouts)) |
500 | for { |
501 | - if dialer.Dial() == nil { |
502 | + if f() == nil { |
503 | return dialAttempts + 1 |
504 | } |
505 | if dialAttempts < numTimeouts { |
506 | @@ -65,7 +64,7 @@ |
507 | } else { |
508 | timeout = Timeouts[numTimeouts-1] |
509 | } |
510 | - timeout += dialer.Jitter(timeout) |
511 | + timeout += jitter(timeout) |
512 | dialAttempts++ |
513 | select { |
514 | case <-quitRedialing: |
515 | @@ -75,6 +74,13 @@ |
516 | } |
517 | } |
518 | |
519 | +// AutoRedialer takes a Dialer and retries its Dial() method until it |
520 | +// stops returning an error. It does exponential (optionally |
521 | +// jitter'ed) backoff. |
522 | +func AutoRedial(dialer Dialer) uint32 { |
523 | + return AutoRetry(dialer.Dial, dialer.Jitter) |
524 | +} |
525 | + |
526 | func init() { |
527 | ps := []int{1, 2, 5, 11, 19, 37, 67, 113, 191} // 3 pₙ₊₁ ≥ 5 pₙ |
528 | Timeouts = make([]time.Duration, len(ps)) |
I think main is testable if it gets split in some parts