Skip to content

Commit adda914

Browse files
afrizaandreykaipov
authored andcommitted
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 67a7278 commit adda914

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
@@ -172,10 +172,14 @@ func (c *Client) connect() (err error) {
172172
go c.handleRawServerMessages(authComplete)
173173
go c.handleOpcodes(authComplete)
174174

175+
timeout, timer := newTimeoutTimer(c.ResponseTimeout * time.Millisecond)
175176
select {
176177
case a := <-authComplete:
178+
if timer != nil {
179+
timer.Stop()
180+
}
177181
return a
178-
case <-time.After(c.ResponseTimeout * time.Millisecond):
182+
case <-timeout:
179183
return fmt.Errorf("timeout waiting for authentication: %dms", c.ResponseTimeout)
180184
}
181185
}
@@ -355,7 +359,7 @@ func (c *Client) writeEvent(event interface{}) {
355359
// incoming events was full (but might not be by now),
356360
// so safely read off the oldest, and write the latest
357361
select {
358-
case _ = <-c.IncomingEvents:
362+
case <-c.IncomingEvents:
359363
default:
360364
}
361365

@@ -369,3 +373,15 @@ func (c *Client) Listen(f func(interface{})) {
369373
f(event)
370374
}
371375
}
376+
377+
// newTimeoutTimer is an alternative to time.After with the possibility to cancel
378+
// the underlying time.Timer to achieve better efficiency.
379+
// time.Duration d <= 0 means no timeout or waiting forever.
380+
// See https://pkg.go.dev/time#After
381+
func newTimeoutTimer(d time.Duration) (timeout <-chan time.Time, timer *time.Timer) {
382+
if d > 0 {
383+
timer = time.NewTimer(d)
384+
timeout = timer.C
385+
}
386+
return
387+
}

0 commit comments

Comments
 (0)