Skip to content

Any way to wait for a Reply to complete? #88

@rileym-arcules

Description

@rileym-arcules

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", &params, &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
		}
	}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions