-
Notifications
You must be signed in to change notification settings - Fork 241
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
Handle WebSocket handshake timeouts #422
Conversation
Added new option handshake-timeout for websocket client
Related to #346 More like request for discussion. Some opened questions
|
@shilder Regarding |
src/aleph/http/client.clj
Outdated
@@ -609,6 +614,16 @@ | |||
([_ ctx] | |||
(let [ch (.channel ctx)] | |||
(reset! in (netty/buffered-source ch (constantly 1) 16)) | |||
|
|||
;; Start handshake timeout timer | |||
(reset! timeout-task |
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 was trying to figure out why you used the .in
accessor here, and realized that manifold.time/in
doesn't allow it to be cancelled. That's my bad, I'm going to merge these changes in and then fix the underlying method so we don't have to reach under the covers.
3f940ab
to
075960b
Compare
@kachayev it seems this no longer merges after I brought in the ping functionality, since you have more familiarity with that would you mind getting it into order? |
@ztellman Sure, I'll take care. |
src/aleph/http/client.clj
Outdated
(fn [] | ||
;; if there was no answer after handshake was sent - close channel | ||
(d/error! d (WebSocketHandshakeTimeoutException. "WebSocket handshake timeout")) | ||
(netty/close ctx)))) |
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.
We're not on I/O thread here, so we should probably close the channel, not the context. Right? @ztellman
src/aleph/http/client.clj
Outdated
|
||
;; Start handshake timeout timer | ||
(reset! timeout-task | ||
(.in time/*clock* |
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.
One another thing... Maybe it's better to use EventLoop executor to schedule the task (ctx.executor().schedule
) instead of manifold's clock? We can also just trigger user event from the runnable and check if the handshake was complete in :user-triggered
. It seems like this approach would leave fewer spaces for race conditions. What do you think? @shilder @ztellman
I still wonder why this functionality is not implemented in Netty, e.g. SslHandler
supports handshake timeout as a parameter. I'm going to open an issue to start a discussion there.
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.
One another thing... Maybe it's better to use EventLoop executor to schedule the task (ctx.executor().schedule) instead of manifold's clock
Yes, we can use EventExecutor
and Netty is using it internally in IdleStateHandler
to schedule timeout handlers.
And about :user-triggered
- yes, it will work, but I'm not sure how it will help with race conditions ? AFAIU Future#cancel
provides synchronization point. Or maybe you are talking about situation where context is closed by timeout handler while another thread awaits on Future#cancel
? I'm not a Netty expert, so I'm not sure how it handles serialization of events for context
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.
Not only for IdleTimeoutHandler but for all timeout tasks. Future canceling is what I want to avoid here specifically because of a synchronization: it might hurt performance when you introduce sync primitives to the pipeline running on I/O thread.
If you don’t mind, I can update your PR.
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.
If you don’t mind, I can update your PR.
Sure, go ahead
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.
On it!
The more I work with this functionality, the more I wonder why don't we use Netty's |
@shilder I've reimplemented timeouts, please double check on your side. Notable changes:
I've also added a test case to check that the solution works. Should we do the same for a server handler? |
From what I can see, there's no necessary to introduce the same for server's handshake, as it's just about flushing response to the client. @ztellman Now ready for review/merge. |
This has conflicts with the other WS changes I merged, but will merge once those are resolved. |
@ztellman Done! |
@ztellman Fixed conflicts here. |
I'm going to rebase to 1.0.0 to merge with latest changes there. Substantial portion of the code is intertwined with websockets pipeline changes we've made so far. |
As of now, merging into 1.0.0 branch to accumulate pre-release changes there. |
Added new option handshake-timeout for websocket client