Merge lp:~chipaca/ubuntu-push/client-v0-p5 into lp:ubuntu-push

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: 52
Merged at revision: 49
Proposed branch: lp:~chipaca/ubuntu-push/client-v0-p5
Merge into: lp:ubuntu-push
Prerequisite: lp:~chipaca/ubuntu-push/client-v0-p4
Diff against target: 153 lines (+107/-10)
2 files modified
client/client.go (+52/-10)
client/client_test.go (+55/-0)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/client-v0-p5
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+204561@code.launchpad.net

Commit message

added handleConnState

Description of the change

Added handleConnState to deal with connectivity events.

To post a comment you must log in.
lp:~chipaca/ubuntu-push/client-v0-p5 updated
49. By John Lenton

oops, it's no longer AutoRetry

50. By John Lenton

Merged client-v0-p4 into client-v0-p5.

51. By John Lenton

fixed tests broken by changes to session

52. By John Lenton

Merged client-v0-p4 into client-v0-p5.

Revision history for this message
Samuele Pedroni (pedronis) wrote :

58 + panic("Don't know how to handle session creation failure.")

this panic should contain err

65 + client.sessionRetrierStopper <- true

should the autoretrier stopper be unbuffered or buffered if it's unbuffered we risk to be trying in two places to dial, no?

Revision history for this message
Samuele Pedroni (pedronis) wrote :

75 + // disconnected
76 + if client.sessionRetrierStopper != nil {
77 + client.sessionRetrierStopper <- true
78 + client.sessionRetrierStopper = nil
79 + } else {
80 + client.session.Close()
81 + }

it would be nice if that code was just spelled client.session.Close()

Revision history for this message
John Lenton (chipaca) wrote :

the panic() is changed to a return err a little further down the pipeline.

the retrierStopper needs to be buffered because it's entirely possible there's nobody listening at the other end any more. It does mean we're not waiting for one to finish before starting the next, though.

I'll be moving that logic into session in a later branch, ok?

Revision history for this message
John Lenton (chipaca) wrote :

bug lp:1276199 for the session retry rework.

Revision history for this message
Samuele Pedroni (pedronis) wrote :

ok, but see bug and as discussed

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/client.go'
2--- client/client.go 2014-02-03 16:14:16 +0000
3+++ client/client.go 2014-02-04 13:40:08 +0000
4@@ -27,6 +27,7 @@
5 "launchpad.net/ubuntu-push/bus/networkmanager"
6 "launchpad.net/ubuntu-push/bus/notifications"
7 "launchpad.net/ubuntu-push/bus/urldispatcher"
8+ "launchpad.net/ubuntu-push/client/session"
9 "launchpad.net/ubuntu-push/config"
10 "launchpad.net/ubuntu-push/logger"
11 "launchpad.net/ubuntu-push/util"
12@@ -47,16 +48,19 @@
13
14 // Client is the Ubuntu Push Notifications client-side daemon.
15 type Client struct {
16- config ClientConfig
17- log logger.Logger
18- pem []byte
19- idder identifier.Id
20- deviceId string
21- notificationsEndp bus.Endpoint
22- urlDispatcherEndp bus.Endpoint
23- connectivityEndp bus.Endpoint
24- connCh chan bool
25- actionsCh <-chan notifications.RawActionReply
26+ config ClientConfig
27+ log logger.Logger
28+ pem []byte
29+ idder identifier.Id
30+ deviceId string
31+ notificationsEndp bus.Endpoint
32+ urlDispatcherEndp bus.Endpoint
33+ connectivityEndp bus.Endpoint
34+ connCh chan bool
35+ connState bool
36+ actionsCh <-chan notifications.RawActionReply
37+ session *session.ClientSession
38+ sessionRetrierStopper chan bool
39 }
40
41 // Configure loads the configuration specified in configPath, and sets it up.
42@@ -119,3 +123,41 @@
43 client.actionsCh = actionsCh
44 return err
45 }
46+
47+// handleConnState deals with connectivity events
48+func (client *Client) handleConnState(connState bool) {
49+ if client.connState == connState {
50+ // nothing to do!
51+ return
52+ }
53+ client.connState = connState
54+ if client.session == nil {
55+ sess, err := session.NewSession(string(client.config.Addr), client.pem,
56+ client.config.ExchangeTimeout.Duration, client.deviceId, client.log)
57+ if err != nil {
58+ panic("Don't know how to handle session creation failure.")
59+ }
60+ client.session = sess
61+ }
62+ if connState {
63+ // connected
64+ if client.sessionRetrierStopper != nil {
65+ client.sessionRetrierStopper <- true
66+ client.sessionRetrierStopper = nil
67+ }
68+ ar := &util.AutoRetrier{
69+ make(chan bool, 1),
70+ client.session.Dial,
71+ util.Jitter}
72+ client.sessionRetrierStopper = ar.Stop
73+ go ar.Retry()
74+ } else {
75+ // disconnected
76+ if client.sessionRetrierStopper != nil {
77+ client.sessionRetrierStopper <- true
78+ client.sessionRetrierStopper = nil
79+ } else {
80+ client.session.Close()
81+ }
82+ }
83+}
84
85=== modified file 'client/client_test.go'
86--- client/client_test.go 2014-02-04 13:40:07 +0000
87+++ client/client_test.go 2014-02-04 13:40:08 +0000
88@@ -22,6 +22,7 @@
89 . "launchpad.net/gocheck"
90 "launchpad.net/ubuntu-push/bus/networkmanager"
91 testibus "launchpad.net/ubuntu-push/bus/testing"
92+ "launchpad.net/ubuntu-push/client/session"
93 "launchpad.net/ubuntu-push/logger"
94 helpers "launchpad.net/ubuntu-push/testing"
95 "launchpad.net/ubuntu-push/testing/condition"
96@@ -277,3 +278,57 @@
97 c.Check(cli.takeTheBus(), NotNil)
98 c.Check(cli.actionsCh, IsNil)
99 }
100+
101+/*****************************************************************
102+ handleConnState tests
103+******************************************************************/
104+
105+func (cs *clientSuite) TestHandleConnStateD2C(c *C) {
106+ cli := new(Client)
107+
108+ // let's pretend the client had a previous attempt at connecting still pending
109+ // (hard to trigger in real life, but possible)
110+ cli.sessionRetrierStopper = make(chan bool, 1)
111+
112+ c.Assert(cli.connState, Equals, false)
113+ cli.handleConnState(true)
114+ c.Check(cli.connState, Equals, true)
115+ c.Assert(cli.session, NotNil)
116+ c.Check(cli.session.State(), Equals, session.Disconnected)
117+}
118+
119+func (cs *clientSuite) TestHandleConnStateSame(c *C) {
120+ cli := new(Client)
121+ // here we want to check that we don't do anything
122+ c.Assert(cli.session, IsNil)
123+ c.Assert(cli.connState, Equals, false)
124+ cli.handleConnState(false)
125+ c.Check(cli.session, IsNil)
126+
127+ cli.connState = true
128+ cli.handleConnState(true)
129+ c.Check(cli.session, IsNil)
130+}
131+
132+func (cs *clientSuite) TestHandleConnStateC2D(c *C) {
133+ cli := new(Client)
134+ cli.session, _ = session.NewSession(string(cli.config.Addr), cli.pem, cli.config.ExchangeTimeout.Duration, cli.deviceId, noisylog)
135+ cli.session.Dial()
136+ cli.connState = true
137+
138+ // cli.session.State() will be "Error" here, for now at least
139+ c.Check(cli.session.State(), Not(Equals), session.Disconnected)
140+ cli.handleConnState(false)
141+ c.Check(cli.session.State(), Equals, session.Disconnected)
142+}
143+
144+func (cs *clientSuite) TestHandleConnStateC2DPending(c *C) {
145+ cli := new(Client)
146+ cli.session, _ = session.NewSession(string(cli.config.Addr), cli.pem, cli.config.ExchangeTimeout.Duration, cli.deviceId, noisylog)
147+ cli.sessionRetrierStopper = make(chan bool, 1)
148+ cli.connState = true
149+
150+ cli.handleConnState(false)
151+ c.Check(cli.session.State(), Equals, session.Disconnected)
152+ c.Check(cli.sessionRetrierStopper, IsNil)
153+}

Subscribers

People subscribed via source and target branches