Skip to content

Commit 17b0d5c

Browse files
committed
1 parent 7316618 commit 17b0d5c

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

jsonrpc2.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,15 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
168168
ctx = h.Request(ctx, c, Send, req)
169169
}
170170

171-
// we have to add ourselves to the pending map before we send, otherwise we
172-
// are racing the response
173-
rchan := make(chan *WireResponse)
171+
// We have to add ourselves to the pending map before we send, otherwise we
172+
// are racing the response. Also add a buffer to rchan, so that if we get a
173+
// wire response between the time this call is cancelled and id is deleted
174+
// from c.pending, the send to rchan will not block.
175+
rchan := make(chan *WireResponse, 1)
174176
c.pendingMu.Lock()
175177
c.pending[id] = rchan
176178
c.pendingMu.Unlock()
177179
defer func() {
178-
// clean up the pending response handler on the way out
179180
c.pendingMu.Lock()
180181
delete(c.pending, id)
181182
c.pendingMu.Unlock()
@@ -340,22 +341,19 @@ func (c *Conn) Run(ctx context.Context) error {
340341
}()
341342

342343
case msg.ID != nil: // msg.ID not nil, handle the response
343-
// we have a response, get the pending entry from the map
344+
// If method is not set, this should be a response, in which case we must
345+
// have an id to send the response back to the caller.
344346
c.pendingMu.Lock()
345-
rchan := c.pending[*msg.ID]
346-
if rchan != nil {
347-
delete(c.pending, *msg.ID)
348-
}
347+
rchan, ok := c.pending[*msg.ID]
349348
c.pendingMu.Unlock()
350-
351-
// send the reply to the channel
352-
resp := &WireResponse{
353-
Result: msg.Result,
354-
Error: msg.Error,
355-
ID: msg.ID,
349+
if ok {
350+
resp := &WireResponse{
351+
Result: msg.Result,
352+
Error: msg.Error,
353+
ID: msg.ID,
354+
}
355+
rchan <- resp
356356
}
357-
rchan <- resp
358-
close(rchan) // for rchan range loop
359357

360358
default:
361359
for _, h := range c.handlers {
@@ -430,9 +428,9 @@ func (r *Request) Reply(ctx context.Context, result interface{}, reqErr error) e
430428
return err
431429
}
432430
resp := &WireResponse{
433-
JSONRPC: Version,
434-
Result: raw,
435-
ID: r.ID,
431+
// JSONRPC: Version,
432+
Result: raw,
433+
ID: r.ID,
436434
}
437435
if reqErr != nil {
438436
var callErr *Error

0 commit comments

Comments
 (0)