Skip to content

Commit 16e27c6

Browse files
committed
Use time.NewTimer() instead of time.After()
For efficiency, cancel time.Timer after no longer needed. See https://pkg.go.dev/time#After
1 parent 37eec5e commit 16e27c6

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

api/client.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,13 @@ func (c *Client) SendRequest(requestBody Params, responseBody interface{}) error
6868
}
6969

7070
var response *opcodes.RequestResponse
71+
timeout, timer := newTimeoutTimer(c.ResponseTimeout * time.Millisecond)
7172
select {
7273
case response = <-c.IncomingResponses:
73-
case <-time.After(c.ResponseTimeout * time.Millisecond):
74+
if timer != nil {
75+
timer.Stop()
76+
}
77+
case <-timeout:
7478
return fmt.Errorf("request %s: timeout waiting for response from server", name)
7579
}
7680

@@ -123,3 +127,15 @@ func (c *Client) SendRequest(requestBody Params, responseBody interface{}) error
123127

124128
return nil
125129
}
130+
131+
// newTimeoutTimer is an alternative to time.After with the possibility to cancel
132+
// the underlying time.Timer to achieve better efficiency.
133+
// time.Duration d <= 0 means no timeout or waiting forever.
134+
// See https://pkg.go.dev/time#After
135+
func newTimeoutTimer(d time.Duration) (timeout <-chan time.Time, timer *time.Timer) {
136+
if d > 0 {
137+
timer = time.NewTimer(d)
138+
timeout = timer.C
139+
}
140+
return
141+
}

client.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,14 @@ func (c *Client) connect() (err error) {
156156
go c.handleRawServerMessages(authComplete)
157157
go c.handleOpcodes(authComplete)
158158

159+
timeout, timer := newTimeoutTimer(c.ResponseTimeout * time.Millisecond)
159160
select {
160161
case a := <-authComplete:
162+
if timer != nil {
163+
timer.Stop()
164+
}
161165
return a
162-
case <-time.After(c.ResponseTimeout * time.Millisecond):
166+
case <-timeout:
163167
return fmt.Errorf("timeout waiting for authentication: %dms", c.ResponseTimeout)
164168
}
165169
}
@@ -339,7 +343,7 @@ func (c *Client) writeEvent(event interface{}) {
339343
// incoming events was full (but might not be by now),
340344
// so safely read off the oldest, and write the latest
341345
select {
342-
case _ = <-c.IncomingEvents:
346+
case <-c.IncomingEvents:
343347
default:
344348
}
345349

@@ -353,3 +357,15 @@ func (c *Client) Listen(f func(interface{})) {
353357
f(event)
354358
}
355359
}
360+
361+
// newTimeoutTimer is an alternative to time.After with the possibility to cancel
362+
// the underlying time.Timer to achieve better efficiency.
363+
// time.Duration d <= 0 means no timeout or waiting forever.
364+
// See https://pkg.go.dev/time#After
365+
func newTimeoutTimer(d time.Duration) (timeout <-chan time.Time, timer *time.Timer) {
366+
if d > 0 {
367+
timer = time.NewTimer(d)
368+
timeout = timer.C
369+
}
370+
return
371+
}

0 commit comments

Comments
 (0)