-
-
Notifications
You must be signed in to change notification settings - Fork 193
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
Add Jetty 11 adapter #447
base: master
Are you sure you want to change the base?
Add Jetty 11 adapter #447
Conversation
Requires further review. This is a minor but potentially BREAKING change. Zero urgency, consider holding till next breaking set. Before this commit: Client-side `[:chsk/ws-ping]` events are wrapped to `[:chsk/recv [:chsk/ws-ping]]` when `wrap-recv-evs?` is true. After this commit: Client-side `[:chsk/ws-ping` events are NOT wrapped, even when `wrap-recv-evs?` is true. MOTIVATION: While `:chsk/ping` is indeed pushed from server, `:chsk/recv` is in practice reserved for user-level events. Keeping it that way may be better (more convenient for users).
Thanks so much for this Alex! I've got my hands a bit full atm with some other open source tasks, but will definitely get this reviewed+merged the next time I'm on batched Sente work. Will be really nice to have this in 👍 |
No worries! Thanks :) |
@ptaoussanis any idea when this will be merged? Thanks! |
@awb99 Are you blocking on this? Would you need a full release, or just a merge? |
I am stuck to a very old sente version that still has jetty support. I would like to update to a more uptodate version of sente that again supports jetty. I have two reasons: 1) old jetty needs websocket handlers to be marked in the config as such (which means my routing table needs to be done effectively twice, or at least my config becomes more convoluted). 2) old sente versions sometimes to not receive disconnected client notification, so I believe I am sometimes sending push event's to clients that are already gone. I could just use a git commit ID to refer to sente via deps.edn if this is what you refer to. I really would like to upgrade ... but I prefer to do it once it is clear the new code works. Thanks! |
Thanks, and just to clarify - would you need a full release, or just a review and merge of this PR? |
If you just review and merge, then I can use it in deps.edn projects fine. And if it is helpful to you I could try it in the next 2-4 weeks on some of my apps and report here in case there are issues before you do a full release. |
That'd be great, thank you! 🙏 I've just pushed v1.20.0-SNAPSHOT without fully reviewing or testing this PR except for adding missing dependencies, etc. Please let me know if/when you've had an opportunity to test. The reference example includes tools for testing both WebSocket and AJAX features. |
Unfortunately I cannot add snapshot dependencies; most of my libraries are on clojars, and I cannot depend |
I've just added the relevant (temporary, experimental) commits to master 👍 |
@awb99 Have you had any opportunity to test this adapter? I'm aiming to cut a new stable release shortly, and it'd be nice to have this in if possible. |
…narson) Not officially tested, waiting on confirmation from users that this works as intended
Actually, I'll just go ahead and merge this as v1.20 RC1. Hopefully someone can try the adapter out and confirm that it works as expected before v1.20 final - will keep the PR open till then. |
Heads up: upon trying the current release candidate in a project of mine, I immediately get a |
@daniels Thanks for the heads-up Daniel! Is there any other info you can share (ns, etc.)? It seems to be running fine on my side, but I might be missing something. |
I'm investigating, but I can share the following stack trace already.
|
OK, good news. What happened is that I changed the version in |
Okay, happy to hear that! Thanks for updating, and for the testing - much appreciated 🙏 |
Nice to see Jetty support added in RC1! Gave it a spin, but I ran into an issue. It seems like the current implementation is tied to Jetty 11 due to Would it make sense to dynamically import based on the Jetty version or create version-specific adapters? I couldn’t sort out the dynamic import part, so any ideas are welcome. |
@stefanroex Hi Stefan, thanks for pinging about this- It'd definitely be nice to have the Jetty adapter support additional version/s if possible. I'm not familiar on the details of what'd need to change from version to version - but I can help with the conditional compilation (dynamic import) if you or someone else can provide an example of the relevant diffs needed between versions. |
@ptaoussanis Jetty 12’s working fine on my machine so far. Planning to roll it out gradually in production to see how it holds up. So maybe more changes are required. But for now the difference between jetty 11 and 12 is minimal. Instead of using
It should import and extend-type for class |
Thanks! That should be easy to do dynamically (or at least, at compile time). I'll wait on confirmation from you that everything looks good, then I'll add the change 👍 |
We'll start using websockets in production by the end of the year, though I’m not sure if you want to wait that long. Right now, it’s running smoothly in dev, staging, and production (behind a feature flag for a small user set). |
AFAICT, the code doesn't handle timeouts properly. I.e. |
@ptaoussanis Right, but that only substitutes CCE with NPE. Perhaps a custom exception makes sense, or On a separate topic - surprisingly, I can't quite get it to work with Jetty 12, even with the aforementioned change. |
Unfortunately can't offer any advice since I've little familiarity with this myself. Have just marked the issue - hopefully someone else (Alex / Stefan?) might be able to make a suggestion! Otherwise I'll try investigate next time I'm on batched Sente work. Edit to add: re: CCE/NPE - would be happy to see a PR for the Jetty adapter (and presumably also Undertow?) for a clearer error, assuming that's the best we can do. Would also be nice to update the docstrings to make it clear what actually happens on timeout (exception is thrown, etc.). |
Ah, so this is why there are some random
Yeah I'm not sure about interaction with Jetty 12. We're running |
@p-himik I’m only running with WebSockets, no Ajax fallback, on Jetty 12. I suspect the |
I think I figured it out, PEBKAC is to blame for at least 80% of it:
I'm not sure what I can improve here to make such errors more tractable. Perhaps close the Sente connection on the server side when there's an error downstream of Sente? @ptaoussanis But what would be a proper way to do it, given As a second-degree consequence, a different potential issue has manifested itself: after receiving HTTP 500 from the WS request, Sente on the client side keeps spamming the server with plain GET requests with no upgrade headers. And due to a potential error in the adapter implementation, Sente on the server side keeps responding with HTTP 200 with an empty body, which after a delay (most likely, the one specified by |
@p-himik Thanks for the update! Is there any urgency from your side to get feedback from me on this? If so, can try make some time this weekend. |
@ptaoussanis No urgency at all, and thanks for confirming that I can safely use |
@stefanroex Do you not experience timeouts? After fixing the initial issue, I'm getting lines like this in the logs, approximately once every 30 seconds:
It's triggered by Even though Sente has a built-in ping-pong mechanism that by default is set to 25 seconds for the server side, the actual ping messages seem to have a longer delay - 28 seconds on the picture, that one time it took less than 30 seconds so I didn't get a timeout exception with reconnection: |
@ptaoussanis Not urgent - maybe I misunderstand something but to me it seems that the documentation of the The current description in However, here you describe it differently: I haven't analyzed Sente's code enough to confirm that the above scenario is exactly what's going on, but at least it corresponds to what I see - after setting |
@p-himik Hi Eugene, thanks for checking on this- It's late here and I'm about to sign off for the night - so I might also be missing something quite obvious ^^ - but it seems the two descriptions are compatible? The actual implementation is (IIRC) as you linked here. There's a fixed-interval check every So the Let's say that
So there should be opportunities to ping at Could it be that you're observing the result of pong's coming back and therefore registering as activity? I.e.:
etc. This'll show as a ping every second interval if there's a successful pong in between each. Does that make sense? Could well be I'm confused, or could be there's some issue with the implementation - will check back in the morning. I'll note that there does seem to be a potential ambiguity in "Ping to keep a WebSocket conn alive if no activity w/in given msecs" since it's not stated whether it's talking about a rolling or fixed window/period. I'll adjust to make that clearer. |
Yeah, same, about to log off. I think the behavior that I've observed and your description are perfectly compatible. It's just that the docs are vague enough to allow for different interpretations. Your description operates with separate discrete time windows, and I was initially thinking in the context of a sliding window of sorts. Because that's how I've seen timeouts generally being implemented - actions reset a timer, and when the timer reaches 0, a timeout exception is triggered. So the longest possible period of inactivity is exactly the setting of the timer. Alas, I can't quite think of an alternative description of the argument that's unambiguous and doesn't take a whole paragraph. |
Makes sense 👍
Unless I'm missing something, I'm not sure this part is right though. I'd assert that the longest period of inactivity remains I'm intentionally considering a pong as activity on the connection - do you not? The purpose of A pong will still keep the connection open. So if we have a 10s In your example the pong is received very shortly after the ping - that's common, but not universal - especially on sketchier mobile connections, etc. A sliding window would indeed trigger pings more frequently, but it's not immediately obvious to me that that would necessarily be preferable. To clarify:
|
Okay after re-reading my post, I finally think I understand the point that you've been making - sorry about the slow uptake ^^ The current behaviour is indeed unintentional, my assertion here was wrong:
Your original example is accurate:
Would be happy to see a PR that switched to a sliding window (and documented that), otherwise I'll do that myself next time I'm on batched Sente work.
|
Created a separate issue for the keep-alive bug here 👍 Apologies for noise on this, just juggling too many things atm. |
Thanks for clarifying how We initially thought Turns out I was seeing the exact same thing as @p-himik but hadn't started debugging it yet. Thanks @p-himik and @ptaoussanis for clarifying! |
I got it to work with the official ring version that uses jetty 11. |
No description provided.