Skip to content

Commit 2516d10

Browse files
committed
fix concurrency
1 parent 78271a6 commit 2516d10

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

client.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net"
88
"regexp"
99
"strings"
10+
"sync"
1011
"time"
1112
)
1213

@@ -57,6 +58,7 @@ type Client struct {
5758
notify chan Notification
5859
disconnect chan struct{}
5960
res []string
61+
mutex sync.Mutex
6062

6163
Server *ServerMethods
6264
}
@@ -234,7 +236,15 @@ func (c *Client) ExecCmd(cmd *Cmd) ([]string, error) {
234236
return nil, ErrNotConnected
235237
}
236238

237-
c.work <- cmd.String()
239+
c.mutex.Lock()
240+
defer c.mutex.Unlock()
241+
242+
select {
243+
case c.work <- cmd.String():
244+
// continue
245+
case <-time.After(c.timeout):
246+
return nil, ErrTimeout
247+
}
238248

239249
select {
240250
case err := <-c.err:

client_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,36 @@ func TestClientBadHeader(t *testing.T) {
230230
// Should never get here
231231
assert.NoError(t, c.Close())
232232
}
233+
234+
func TestConcurrency(t *testing.T) {
235+
s := newServer(t)
236+
if s == nil {
237+
return
238+
}
239+
defer func() {
240+
assert.NoError(t, s.Close())
241+
}()
242+
243+
c, err := NewClient(s.Addr, Timeout(time.Millisecond*100))
244+
if !assert.NoError(t, err) {
245+
return
246+
}
247+
248+
wait := make(chan struct{})
249+
250+
go func() {
251+
for i := 0; i <= 10; i++ {
252+
_, err = c.Server.GroupList()
253+
assert.NoError(t, err)
254+
}
255+
wait <- struct{}{}
256+
}()
257+
258+
for i := 0; i <= 10; i++ {
259+
_, err = c.Server.GroupList()
260+
assert.NoError(t, err)
261+
}
262+
263+
// wait for go routine to finish
264+
<-wait
265+
}

0 commit comments

Comments
 (0)