R
Railway•5mo ago
raf

Abort signal on SSE not working

So I've been rewriting my polling code with Server-sent-events (SSE) to reduce egress fees to railway, and on the server side I've add a abort signal listener to stop the running interval. (I'm using NextJS App directory) here's the code
request.signal.addEventListener("abort", async () => {
console.info("Client disconnected");
clearInterval(interval);
await closeStream();
});
request.signal.addEventListener("abort", async () => {
console.info("Client disconnected");
clearInterval(interval);
await closeStream();
});
On my local computer and on other VPS, it works fine, when the client is closing the EventSource, the server received abort signal directly. However on Railway, the server cannot get the abort signal, and another bug that I found is that SSE connection only can works for around 2 minutes before the server automatically close the connection. Please keep in mind that in another machine everything works normally and there's no connection duration limit, it only happens on Railway. So I suspect that it has to do with Railway Edge Proxy, can anyone clarify and possibly help me with the solution to this problem? Thanks!
41 Replies
Percy
Percy•5mo ago
Project ID: 2fee4431-767f-456a-8835-06cdd70005f7
raf
rafOP•5mo ago
2fee4431-767f-456a-8835-06cdd70005f7
raf
rafOP•5mo ago
Even in the Railway SSE POC, the connection is closed after around 5 minutes, no EventStream coming from network tab after the error is shown POC Url: https://utilities.up.railway.app/sse
No description
raf
rafOP•5mo ago
So after reading the docs, it seems that my suspicion is true, railway edge network only support max duration of 5 minutes for http request But still idk why the abort signal not received by the server
No description
Brody
Brody•5mo ago
the docs are correct, there is indeed a max duration of 5 minutes, and that is not something that can be or will be changed. but the abort signal not being received is interesting, I'll have to look into that.
raf
rafOP•5mo ago
yeah i've the workaround for the 5 minute limit issue, it's fine for that, but not with the abort signal one
Brody
Brody•5mo ago
have you tried listening for a close event?
raf
rafOP•5mo ago
well seems that nextjs doesn't provide that, and also this is the example sent by the vercel team itself https://github.com/vercel/next.js/discussions/48427#discussioncomment-5624604
GitHub
Server-Sent Events don't work in Next API routes · vercel next.js ·...
Bug report Describe the bug When using Next's API routes, chunks that are written with res.write aren't sent until after res.end() is called. To Reproduce Steps to reproduce the behavior, p...
Brody
Brody•5mo ago
so what happens when your client closes the event source? nothing happens?
raf
rafOP•5mo ago
in nextjs, it seems that close event are on abort signal, and on abort, i will log it and also clear the running interval as the written code in this thread however, the abort signal is not called when i deployed on railway been trying to disable/enable the edge proxy but the results stay same
raf
rafOP•5mo ago
GitHub
Server-Sent Events don't work in Next API routes · vercel next.js ·...
Bug report Describe the bug When using Next's API routes, chunks that are written with res.write aren't sent until after res.end() is called. To Reproduce Steps to reproduce the behavior, p...
Brody
Brody•5mo ago
are you aware that disabling / enabling the edge proxy takes several minutes to take effect?
raf
rafOP•5mo ago
yes i've waited for around 10-15 minutes after enabling/disabling, still no effect
raf
rafOP•5mo ago
(Picture 1) so the expected result is, between this 2 "New connection established" there should be "Client disconnected" log since i open a tab -> close it -> then open it again (Picture 2) however, as you can see, the "Client disconnected" log is not showing between that log, however it does shown late and disconnected together after several time
No description
No description
angelo
angelo•5mo ago
are you using the railway provided domain?
raf
rafOP•5mo ago
no, i'm using cloudflare proxied domain, the domain is staging.tako.id
angelo
angelo•5mo ago
!t
Duchess
Duchess•5mo ago
New reply sent from Help Station thread:
This thread has been escalated to the Railway team.
You're seeing this because this thread has been automatically linked to the Help Station thread.
Brody
Brody•5mo ago
forgot to mention, my sse demo prints connection closed when you close the tab, using the railway provided domain
Duchess
Duchess•5mo ago
New reply sent from Help Station thread:
Hey there, bumping to see if you are closing the connection on your application. We checked our proxy to see if there was any weirdness here and since there is no change of behavior on legacy and V2 we doubt there is something on our end.
You're seeing this because this thread has been automatically linked to the Help Station thread.
raf
rafOP•5mo ago
yes for sure i'm closing the connection, i have mentioned it on this thread post
Brody
Brody•5mo ago
No description
Brody
Brody•5mo ago
open link -> wait 12.332 seconds -> close tab http request logged, and the client disconnected message printed these are the logs of the service for - https://utilities.up.railway.app/sse
angelo
angelo•5mo ago
I wonder if theres some confounding issues with CF and us.
Brody
Brody•5mo ago
yeah, maybe you have some rules set, because i just tested it with a cloudflare proxied domain and it worked all the same - https://utilities.railyard.link/sse going forward, since i can't repo, i'd have to ask you for a minimal reproducible example, otherwise theres not much more we can do for you here unfortunately
raf
rafOP•5mo ago
Okay then, i'll try create a basic minimalistic reproduction code this night (it's 2:50 PM here) after i've done with my work
Brody
Brody•5mo ago
awsome, thanks
raf
rafOP•5mo ago
I've create a minimal reproduction code that you can access here https://github.com/raflymln/unnecessary-quotes however somehow i can't deploy it right now, i'm still debugging the issue, if you guys found out what's error in the build it'd be much appreciated, but no problem if you're busy
GitHub
GitHub - raflymln/unnecessary-quotes: SSE PoC in Next.js 14 App Dir...
SSE PoC in Next.js 14 App Directory. Contribute to raflymln/unnecessary-quotes development by creating an account on GitHub.
raf
rafOP•5mo ago
PS: i only cant deploy it to the railway, it's normal in vercel/private server
angelo
angelo•5mo ago
We can't test this if this doesn't deploy ;-;
Brody
Brody•5mo ago
can you give us more information than "i can't deploy it" please
raf
rafOP•5mo ago
sorry, let me get this straight, its deployed, however the sse is not working on railway, i'm still debugging it if it comes from the railway, the docker build, or my code
Brody
Brody•5mo ago
can you give us more information than "sse is not working"
raf
rafOP•5mo ago
can't connect it somehow, i think it comes from my code
Brody
Brody•5mo ago
okay let us know when you have the example working
raf
rafOP•5mo ago
So after a very hardworking and debugging, I found out that it's the bug from the Next.js itself that prevent SSE API to be accessed (damn I spend too much time on this) However, the project can be accessed and can be tested right now. To reproduce my issue on this thread, please read below [Railway Project Information] - Project ID: - 0cd4f47a-c770-45a4-9720-b038cae9b179 (Account 1) - 29a867f5-5cfe-4da3-887d-7fd9728a187f (Account 2) - Source Code: https://github.com/raflymln/unnecessary-quotes - App Sleeping is Enabled, so if the app is not running, might need some time to boot up - New Edge Proxy is Enabled - URL 1: https://unnecessary-quotes-production.up.railway.app (Account 1, US West) - URL 2: https://uq.raflymaulana.me (Account 1, US West) [Cloudflare Proxied] - URL 3: https://sse-test-production.up.railway.app/ (Account 2, Singapore) - URL 4: https://sse-test.tako.id (Account 2, Singapore) [Cloudflare Proxied] [App Information] - Whenever a new SSE connection is created, server will log [SSE] Client connected { connectionId } - Whenever a new SSE connection is deleted, server will log [SSE] Client disconnected { connectionId } - Create a new SSE connection by clicking Start Quote - To delete/stop a connection, you can click Stop Quote or refresh the page since there are beforeunload event that will trigger eventSource.close() - Each client has it's own (kind-of) unique connectionId that can be found at the footer of the page, use that to match with the log on the server - Server has also abort event listener, that will listen whenever the client close the connection with eventSource.close() or if the connection is lost (either from the server [like timeout/http duration limit] or the client ISP issue) [To Reproduce] 1. For Railway Team, make sure you get into the deployment log first 2. Open the website then Start Quote, Stop Quote, Start Quote again, and Stop Quote again 3. The server logs should be structured from Client connected, Client disconnected, and so on... 4. Try to refresh the page while connection is running (Start Quote first, then refresh the page), it should trigger abort on the backend [Consideration] Before you test it, I've tested it and found interesting result, all of that 4 URLs above show the expected result of mine, which the abort signal triggered when the connection closed. However, the code used in this reproduction is pretty much the same handler used for https://staging.tako.id, but the result if pretty different. - (Picture 1) Testing on https://sse-test.tako.id, pretty much doing it's job perfectly like what it should be. It had the same WAF and other Cloudflare configuration as https://staging.tako.id. But compare it to Picture 2 below - (Picture 2) Testing on https://staging.tako.id, as you can see, the delay of the last Sending data to client to Client disconnected takes around 1min of time, also the first connection is closed along with the second connection which kinda questioned me why? Once again, I promise and I've make sure that the code on both the reproduction and the https://staging.tako.id has the same thing going on, from the code to the app usage, but however it returns a different result, so pretty much needed to be checked whether it coming from Railway side or other side. Project ID for https://staging.tako.id is 2fee4431-767f-456a-8835-06cdd70005f7 and it's run on staging environment. Any help would be appreciated :thumbs_up: Thanks!
No description
No description
Brody
Brody•5mo ago
despite you showing that your app can see the abort signal just fine, i went ahead and tested it anyway, and it also works fine
No description
Brody
Brody•5mo ago
as previously mentioned, we would need a reproducible example to be of any help slightly odd time to ask a question, but I just had an idea for a template/demo project and was wondering if I could use most if not all of the react code you wrote for the frontend? id credit you if you would like
raf
rafOP•5mo ago
Yes no problem man! just use it 😄 yeah i still trying to figure it out until now, however for now it's not a critical problem just a bit annoying...
Brody
Brody•5mo ago
if i was in your shoes, i would resort the the process of elimination, from the codebase that is having issues remove code until it works, since your minimal example works, perhaps some bad middleware of sorts?
raf
rafOP•5mo ago
OH i think you're right, middleware.... alright let me test it
Want results from more Discord servers?
Add your server