-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement isConnected method #224
Conversation
tests/testserverclient.nim
Outdated
test "Client close and isConnected": | ||
check client.isConnected() == true | ||
# Is socket server close broken? | ||
# waitFor client.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this test when I try to close the socket client it gets stuck waiting and it looks like the socker server loop never exits/finishes for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a know bug of socket client
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't spend long looking at it. Do you have a suggestion/guidance on how I can fix it? If it isn't trivial, then I'll create an issue for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is here I think, but I have not actually test it because we do not have production code using socket client or server.
var value = await client.transport.readLine(defaultMaxRequestLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just pushed a fix which solves the problem in the tests. Can you review the change when you get a chance? I'm not sure if it might effect something else.
RpcHttpClient actually not using persistent connection like RpcWebsocketClient or RpcSocketClient. RpcHttpClient does not using keep-alive connection. Every request actually a new connection. I don't think we need to add isConnected to RpcHttpClient. |
I see, in that case it will be unimplemented and throw an assertion Defect if called on the RpcClient type. That might create a problem. For example, I've created a type that uses RpcClient and it might be a RpcHttpClient or a RpcWebsocketClient and I'll like to check the connection if an error is thrown in these cases with having to right code that checks what type of instance it is. Perhaps it would be better to simply return true for the RpcHttpClient? The RpcHttpClient does have a connect method already so perhaps isConnected in this context just means that it is ready to send requests. |
I have no objection, although it's a bit misleading technically. But I think it's ok. |
Yes thats true but perhaps if we implement keep alive then it won't matter. In that case, I'll leave it for now. |
this is based on the assumption that connectivity accurately can be established, which is usually not true - ie the normal case is that you discover if you're connected or not on the first read or write from the socket, so the right place to handle reconnections is usually in one of those two places: where you wait for new data to arrive and where you attempt to send stuff. |
What would you suggest for this PR in that case? The overall goal for this PR was to have a way to decide whether to try reconnecting when using websockets and catching an error after issuing a json-rpc request. If the web socket connection is lost then a reconnect is required in order to continue sending data. In the RpcWebSocketClient type the WSSession transport field gets set to nil when the connection is lost and as you said this is only discovered when sending or receiving. Currently the only way for me to handle this is to check if the wsClient.transport field is nil which doesn't seem like a very nice solution. |
The "broad" way of handling this is to have the thing doing the requesting decide if it should retry based on the outcome of the request itself - the way sockets work is that many connection failures are detected when you try to use the socket, so this is usually the best place to "schedule" retries. Wanting to check for |
It sounds like a better design for this might be to simply throw an exception at the time of doing a request which clearly indicates that a reconnect is required. The calling code can then catch and then handle appropriately. I'll close this PR for now and come up with a better solution. |
Having an isConnected method on the RpcClient will be useful for handling reconnection scenarios especially for websockets. At the moment if the websocket server goes offline then restarts the client is disconnected and not reconnected. Having an isConnected proc will allow checking and reconnecting in applications.