Merge lp:~allenap/gwacl/poll-immediately into lp:gwacl

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: 155
Merged at revision: 155
Proposed branch: lp:~allenap/gwacl/poll-immediately
Merge into: lp:gwacl
Diff against target: 66 lines (+29/-4)
2 files modified
poller.go (+19/-4)
poller_test.go (+10/-0)
To merge this branch: bzr merge lp:~allenap/gwacl/poll-immediately
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+172567@code.launchpad.net

Commit message

In performPolling, do an immediate poll before sleeping.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Looks okay, I think it's much harder to follow what's going on now but I don't think it's worth blocking you (although I'm tempted :))

That code is not very readable (especially the new internal poll() method that returns a bool *and* modifies performPolling-level objects)! Part of it, I reckon, is not your fault but is related to the way Go works… but I still wonder if this cannot be improved a tad.

[0]

19 + // Do a single poll, checking for timeout.
20 + poll := func() bool {

Please explain what the returned boolean means.

[1]

20 + poll := func() bool {

Could poll be changed so that it would not modify 'response' and 'err' "in place". That is really confusing, at least to me.

[2]

14 + defer func() {
15 + if err != nil {
16 + response = nil
17 + }
18 + }()

Why did you add that? I suspect it is because an old response from polling number n might be returned along with an error that appended during poll number n+1… please put a comment to explain what purpose this serves.

review: Approve
lp:~allenap/gwacl/poll-immediately updated
155. By Gavin Panella

Don't modify variables in enclosing scope.

Revision history for this message
Gavin Panella (allenap) wrote :

> [1]
>
> 20      +    poll := func() bool {
>
> Could poll be changed so that it would not modify 'response' and 'err' "in
> place".  That is really confusing, at least to me.

I've updated it to not modify the variables from the enclosing
scope. Please take another look.

Revision history for this message
Raphaël Badin (rvb) wrote :

> > [1]
> >
> > 20      +    poll := func() bool {
> >
> > Could poll be changed so that it would not modify 'response' and 'err' "in
> > place".  That is really confusing, at least to me.
>
> I've updated it to not modify the variables from the enclosing
> scope. Please take another look.

Much better I think! More readable, plus you've been able to rid of the response-cleaning deferred.

Thanks for taking the time to do this.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'poller.go'
2--- poller.go 2013-04-16 13:09:54 +0000
3+++ poller.go 2013-07-02 14:24:22 +0000
4@@ -22,22 +22,37 @@
5 func performPolling(poller poller, interval time.Duration, timeout time.Duration) (*x509Response, error) {
6 timeoutChannel := time.After(timeout)
7 ticker := time.Tick(interval)
8- for _ = range ticker {
9+ // Function to do a single poll, checking for timeout. The bool returned
10+ // indicates if polling is finished, one way or another.
11+ poll := func() (bool, *x509Response, error) {
12 // This may need to tolerate some transient failures, such as network
13 // failures that may go away after a few retries.
14 select {
15 case <-timeoutChannel:
16- return nil, fmt.Errorf("polling timed out waiting for an asynchronous operation")
17+ return true, nil, fmt.Errorf("polling timed out waiting for an asynchronous operation")
18 default:
19 response, pollerErr := poller.poll()
20 done, err := poller.isDone(response, pollerErr)
21 if err != nil {
22- return nil, err
23+ return true, nil, err
24 }
25 if done {
26- return response, nil
27+ return true, response, nil
28 }
29 }
30+ return false, nil, nil
31+ }
32+ // Do an initial poll.
33+ done, response, err := poll()
34+ if done {
35+ return response, err
36+ }
37+ // Poll every interval.
38+ for _ = range ticker {
39+ done, response, err := poll()
40+ if done {
41+ return response, err
42+ }
43 }
44 // This code cannot be reached but Go insists on having a return or a panic
45 // statement at the end of this method. Sigh.
46
47=== modified file 'poller_test.go'
48--- poller_test.go 2013-06-27 10:55:35 +0000
49+++ poller_test.go 2013-07-02 14:24:22 +0000
50@@ -62,6 +62,16 @@
51 return false, nil
52 }
53
54+func (suite *pollerSuite) TestperformPollingPollsOnceImmediately(c *C) {
55+ poller := newTestPoller(0, 0)
56+ interval := time.Second * 10
57+ start := time.Now()
58+ response, err := performPolling(poller, interval, interval*2)
59+ c.Assert(err, Equals, nil)
60+ c.Assert(time.Since(start) < interval, Equals, true)
61+ c.Assert(response, DeepEquals, &testPollerResponse)
62+}
63+
64 func (suite *pollerSuite) TestperformPollingReturnsError(c *C) {
65 poller := newTestPoller(0, 1)
66 response, err := performPolling(poller, time.Nanosecond, time.Minute)

Subscribers

People subscribed via source and target branches

to all changes: