Skip to content

Commit 4cce303

Browse files
davsebydemget
authored andcommitted
bot,api: fix stop channel race
1 parent 71ac299 commit 4cce303

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

api.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@ func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
2727
return nil, err
2828
}
2929

30-
// Cancel the request immediately without waiting for the timeout when bot is about to stop.
30+
// Cancel the request immediately without waiting for the timeout
31+
// when bot is about to stop.
3132
// This may become important if doing long polling with long timeout.
32-
exit := make(chan struct{})
33-
defer close(exit)
3433
ctx, cancel := context.WithCancel(context.Background())
3534
defer cancel()
3635

3736
go func() {
37+
b.stopMu.RLock()
38+
stopCh := b.stopClient
39+
b.stopMu.RUnlock()
40+
3841
select {
39-
case <-b.stopClient:
42+
case <-stopCh:
4043
cancel()
41-
case <-exit:
44+
case <-ctx.Done():
4245
}
4346
}()
4447

bot.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"regexp"
1111
"strconv"
1212
"strings"
13+
"sync"
1314
"time"
1415
)
1516

@@ -81,7 +82,9 @@ type Bot struct {
8182
parseMode ParseMode
8283
stop chan chan struct{}
8384
client *http.Client
84-
stopClient chan struct{}
85+
86+
stopMu sync.RWMutex
87+
stopClient chan struct{}
8588
}
8689

8790
// Settings represents a utility struct for passing certain
@@ -198,10 +201,14 @@ func (b *Bot) Start() {
198201
}
199202

200203
// do nothing if called twice
204+
b.stopMu.Lock()
201205
if b.stopClient != nil {
206+
b.stopMu.Unlock()
202207
return
203208
}
209+
204210
b.stopClient = make(chan struct{})
211+
b.stopMu.Unlock()
205212

206213
stop := make(chan struct{})
207214
stopConfirm := make(chan struct{})
@@ -221,17 +228,20 @@ func (b *Bot) Start() {
221228
close(stop)
222229
<-stopConfirm
223230
close(confirm)
224-
b.stopClient = nil
225231
return
226232
}
227233
}
228234
}
229235

230236
// Stop gracefully shuts the poller down.
231237
func (b *Bot) Stop() {
238+
b.stopMu.Lock()
232239
if b.stopClient != nil {
233240
close(b.stopClient)
241+
b.stopClient = nil
234242
}
243+
b.stopMu.Unlock()
244+
235245
confirm := make(chan struct{})
236246
b.stop <- confirm
237247
<-confirm

0 commit comments

Comments
 (0)