Merge lp:~chipaca/ubuntu-push/session-refactor-002 into lp:ubuntu-push/automatic

Proposed by John Lenton
Status: Work in progress
Proposed branch: lp:~chipaca/ubuntu-push/session-refactor-002
Merge into: lp:ubuntu-push/automatic
Prerequisite: lp:~chipaca/ubuntu-push/session-refactor-001
Diff against target: 209 lines (+130/-7)
3 files modified
client/client.go (+7/-3)
client/client_test.go (+5/-3)
client/session/session.go (+118/-1)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/session-refactor-002
Reviewer Review Type Date Requested Status
Ubuntu Push Hackers Pending
Review via email: mp+249500@code.launchpad.net

This proposal supersedes a proposal from 2015-02-12.

To post a comment you must log in.

Unmerged revisions

367. By John Lenton

tmp checking; does not work

366. By John Lenton

protect the chs with a lock. any lock will do.

365. By John Lenton

added SetChForTesting, for testing

364. By John Lenton

first step

363. By John Lenton

Merged explicit-check-for-oversize-webcheck-response-bodies into session-refactor.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'client/client.go'
--- client/client.go 2015-02-12 14:49:15 +0000
+++ client/client.go 2015-02-12 14:49:16 +0000
@@ -478,16 +478,20 @@
478// doLoop connects events with their handlers478// doLoop connects events with their handlers
479func (client *PushClient) doLoop(connhandler func(bool), bcasthandler func(*session.BroadcastNotification) error, ucasthandler func(session.AddressedNotification) error, errhandler func(error), unregisterhandler func(*click.AppId), accountshandler func()) {479func (client *PushClient) doLoop(connhandler func(bool), bcasthandler func(*session.BroadcastNotification) error, ucasthandler func(session.AddressedNotification) error, errhandler func(error), unregisterhandler func(*click.AppId), accountshandler func()) {
480 for {480 for {
481 bch := client.session.GetBroadcastCh()
482 uch := client.session.GetNotificationsCh()
483 ech := client.session.GetErrCh()
484 client.log.Debugf("XXX S: %#v -- B:%v U:%v E:%v", client.session, bch, uch, ech)
481 select {485 select {
482 case <-client.accountsCh:486 case <-client.accountsCh:
483 accountshandler()487 accountshandler()
484 case state := <-client.connCh:488 case state := <-client.connCh:
485 connhandler(state)489 connhandler(state)
486 case bcast := <-client.session.GetBroadcastCh():490 case bcast := <-bch:
487 bcasthandler(bcast)491 bcasthandler(bcast)
488 case aucast := <-client.session.GetNotificationsCh():492 case aucast := <-uch:
489 ucasthandler(aucast)493 ucasthandler(aucast)
490 case err := <-client.session.GetErrCh():494 case err := <-ech:
491 errhandler(err)495 errhandler(err)
492 case count := <-client.sessionConnectedCh:496 case count := <-client.sessionConnectedCh:
493 client.log.Debugf("session connected after %d attempts", count)497 client.log.Debugf("session connected after %d attempts", count)
494498
=== modified file 'client/client_test.go'
--- client/client_test.go 2015-02-12 14:49:15 +0000
+++ client/client_test.go 2015-02-12 14:49:16 +0000
@@ -714,7 +714,7 @@
714 cli.hasConnectivity = true714 cli.hasConnectivity = true
715 defer cli.session.Close()715 defer cli.session.Close()
716 cli.handleErr(errors.New("bananas"))716 cli.handleErr(errors.New("bananas"))
717 c.Check(cs.log.Captured(), Matches, ".*session exited.*bananas\n")717 c.Check(cs.log.Captured(), Matches, "(?ism).*session exited.*bananas")
718}718}
719719
720/*****************************************************************720/*****************************************************************
@@ -775,8 +775,7 @@
775 cli.session.Dial()775 cli.session.Dial()
776 cli.hasConnectivity = true776 cli.hasConnectivity = true
777777
778 // cli.session.State() will be "Error" here, for now at least778 c.Check(cli.session.State(), Equals, session.Disconnected) // internally Error, but invisible now
779 c.Check(cli.session.State(), Not(Equals), session.Disconnected)
780 cli.handleConnState(false)779 cli.handleConnState(false)
781 c.Check(cli.session.State(), Equals, session.Disconnected)780 c.Check(cli.session.State(), Equals, session.Disconnected)
782}781}
@@ -1162,11 +1161,14 @@
1162 c.Check(cli.hasConnectivity, Equals, false)1161 c.Check(cli.hasConnectivity, Equals, false)
1163 cli.connCh <- true1162 cli.connCh <- true
1164 tick()1163 tick()
1164 cs.log.Debugf("================================================================")
1165 c.Check(cli.hasConnectivity, Equals, true)1165 c.Check(cli.hasConnectivity, Equals, true)
1166 cli.connCh <- false1166 cli.connCh <- false
1167 tick()1167 tick()
1168 c.Check(cli.hasConnectivity, Equals, false)1168 c.Check(cli.hasConnectivity, Equals, false)
11691169
1170 cs.log.Debugf("here")
1171
1170 // * session.BroadcastCh to the notifications handler1172 // * session.BroadcastCh to the notifications handler
1171 c.Check(d.bcastCount, Equals, 0)1173 c.Check(d.bcastCount, Equals, 0)
1172 bcastCh <- positiveBroadcastNotification1174 bcastCh <- positiveBroadcastNotification
11731175
=== modified file 'client/session/session.go'
--- client/session/session.go 2015-02-12 14:49:15 +0000
+++ client/session/session.go 2015-02-12 14:49:16 +0000
@@ -37,6 +37,7 @@
37 "launchpad.net/ubuntu-push/logger"37 "launchpad.net/ubuntu-push/logger"
38 "launchpad.net/ubuntu-push/protocol"38 "launchpad.net/ubuntu-push/protocol"
39 "launchpad.net/ubuntu-push/util"39 "launchpad.net/ubuntu-push/util"
40 "runtime"
40)41)
4142
42var (43var (
@@ -132,6 +133,122 @@
132 SetChForTesting(chan *BroadcastNotification, chan AddressedNotification, chan error)133 SetChForTesting(chan *BroadcastNotification, chan AddressedNotification, chan error)
133}134}
134135
136// SessionManager presents a ClientSession interface, but hides the error states.
137type SessionManager struct {
138 session ClientSession
139 serverAddrSpec string
140 conf ClientSessionConfig
141 deviceId string
142 seenStateFactory func() (seenstate.SeenState, error)
143 log logger.Logger
144 lck sync.Mutex
145}
146
147func funcName() string {
148 pc, _, _, _ := runtime.Caller(2)
149 return runtime.FuncForPC(pc).Name()
150}
151
152func (sm *SessionManager) lock() {
153 sm.log.Debugf("[%s] locking...", funcName())
154 sm.lck.Lock()
155 sm.log.Debugf("[%s] locked.", funcName())
156}
157
158func (sm *SessionManager) unlock() {
159 sm.lck.Unlock()
160 sm.log.Debugf("[%s] unlocked.", funcName())
161}
162
163func newSessionManager(serverAddrSpec string, conf ClientSessionConfig,
164 deviceId string, seenStateFactory func() (seenstate.SeenState, error),
165 log logger.Logger) (*SessionManager, error) {
166 sm := &SessionManager{
167 session: nil,
168 serverAddrSpec: serverAddrSpec,
169 conf: conf,
170 deviceId: deviceId,
171 seenStateFactory: seenStateFactory,
172 log: log,
173 }
174 return sm, sm.newSession()
175}
176
177func (sm *SessionManager) newSession() error {
178 if sm.state() != Disconnected {
179 return errors.New("trying to create a new session with non-stopped non-errored one existing.")
180 }
181 sess, err := newSession(sm.serverAddrSpec, sm.conf, sm.deviceId, sm.seenStateFactory, sm.log)
182 if err != nil {
183 return err
184 }
185 sm.session = sess
186 return nil
187}
188
189func (sm *SessionManager) State() ClientSessionState {
190 sm.lock()
191 defer sm.unlock()
192 return sm.state()
193}
194func (sm *SessionManager) state() ClientSessionState {
195 if sm.session == nil {
196 return Disconnected
197 }
198 state := sm.session.State()
199 if state == Error {
200 return Disconnected
201 }
202 return state
203}
204
205func (sm *SessionManager) AutoRedial(done chan uint32) {
206 sm.lock()
207 defer sm.unlock()
208 // sm.newSession()
209 sm.session.AutoRedial(done)
210}
211
212func (sm *SessionManager) Close() {
213 sm.lock()
214 defer sm.unlock()
215 sm.session.Close()
216}
217
218func (sm *SessionManager) ClearCookie() {
219 sm.lock()
220 defer sm.unlock()
221 sm.session.ClearCookie()
222}
223
224func (sm *SessionManager) Dial() error {
225 sm.lock()
226 defer sm.unlock()
227 return sm.session.Dial()
228}
229
230func (sm *SessionManager) GetBroadcastCh() chan *BroadcastNotification {
231 sm.lock()
232 defer sm.unlock()
233 return sm.session.GetBroadcastCh()
234}
235func (sm *SessionManager) GetNotificationsCh() chan AddressedNotification {
236 sm.lock()
237 defer sm.unlock()
238 return sm.session.GetNotificationsCh()
239}
240func (sm *SessionManager) GetErrCh() chan error {
241 sm.lock()
242 defer sm.unlock()
243 return sm.session.GetErrCh()
244}
245
246func (sm *SessionManager) SetChForTesting(bch chan *BroadcastNotification, nch chan AddressedNotification, ech chan error) {
247 sm.lock()
248 defer sm.unlock()
249 sm.session.SetChForTesting(bch, nch, ech)
250}
251
135// ConcreteSession holds a client<->server session and its configuration.252// ConcreteSession holds a client<->server session and its configuration.
136type ConcreteSession struct {253type ConcreteSession struct {
137 // configuration254 // configuration
@@ -191,7 +308,7 @@
191func NewSession(serverAddrSpec string, conf ClientSessionConfig,308func NewSession(serverAddrSpec string, conf ClientSessionConfig,
192 deviceId string, seenStateFactory func() (seenstate.SeenState, error),309 deviceId string, seenStateFactory func() (seenstate.SeenState, error),
193 log logger.Logger) (ClientSession, error) {310 log logger.Logger) (ClientSession, error) {
194 return newSession(serverAddrSpec, conf, deviceId, seenStateFactory, log)311 return newSessionManager(serverAddrSpec, conf, deviceId, seenStateFactory, log)
195}312}
196313
197func newSession(serverAddrSpec string, conf ClientSessionConfig,314func newSession(serverAddrSpec string, conf ClientSessionConfig,

Subscribers

People subscribed via source and target branches