-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Hello!
I'm trying to write a handler where I send a Reply and then need to follow up immediately with a Call within a handler.
My handler looks like so:
func(ctx context.Context, rpcConn *jsonrpc2.Conn, req *jsonrpc2.Request) {
switch req.Method {
case "connect":
// do work
err := rpcConn.Reply(ctx, req.ID, &result)
// here, I need to immediately send a request to the same client
err = rpcConn.Call(ctx, "invite", ¶ms, &next)
// ...
}
}If I try this without the jsonrpc2.AsyncHandler wrapper, the Call call hangs (since it's waiting on the current return I suppose, not really sure why the handler would care about outgoing requests?)
So, I wrap it in the jsonrpc2.AsyncHandler and everything seems to be okay after that. But the problem then is there's a race condition where sometimes the request Call reaches the client before the Reply!
It breaks my matching client code since the result in the Reply returns an identifier as a lookup key that the Call is expecting.
Here's a snippet of the client code that I hope explains it a little better:
// setup Client as the jsonrpc2.AsyncHandler
func (c *Client) Connect(params any) error {
if err := c.conn.Call(ctx, "connect", params, result); err != nil {
// handle
}
c.connected[result.ID] = &foo{}
}
func (c *Client) Handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
switch req.Method {
case "invite":
// parse params
thisFoo, ok := c.connected[params.ID]
if !ok {
// sometimes fails here with !ok
}
}