Detecting HTTP connection closure in Rails - ruby-on-rails

When using Nginx there are times then HTTP 499 is recorded in the error log when the client has prematurely closed their connection (for example, the connection timed out, the user reloaded their browser or pressed Stop or otherwise).
I understand that Nginx is able to detect this because they are the end which will receive the SIGPIPE signal indicating the socket has been closed, however I am wondering if it is possible to get this notice back to Rails at all?
Shopify recently used a very novel approach to detect this in Unicorn before sending the request on to Rails to be processed, however I would like to be able to detect this within the Rails app, such as during a long-running transaction.

After Rails's dispatcher had already started processing the request - there is no connection to the http client anymore, only when the processing is done - the response is headed back to the client.
So basically, there is no way you can tell if the client (e.g: browser) had shutdown the connection while you are already processing it.

Related

Suave runs out of sockets when receiving messages from AWS' SNS service

This is linked to question: Suave stops responding with "Socket failed to accept a client" error
When I first started to use Suave, I was taking commands from a 3rd party service pushing messages and I would have an out of socket situation.
There is now more understanding of the problem:
I am receiving messages that are posted to the SNS service on AWS (it's just a queue). SNS will forward me each message it receives through a HTTP connection, as a POST message.
If I reply with Ok, I will run out of sockets. So this means that Suave is trying to keep the connection open and AWS is somehow initiating a new connection every time.
If I reply with CLOSE, the AWS' delivery starts to become odd and messages get delivered in batches followed by periods of nothing.
Since AWS will not change their system for me, I'm wondering if I can reply Ok but then somehow close the connection in Suave to not run out of sockets. Is it possible?
Or, is there a better way to handle this?

What happens when I call URLSessionTask's task.cancel()?

The reference for this method only says what happens locally on the client, and says nothing about what it potentially sends to the server. Apparently, our server has some challenges with receiving a lot of status code 499 from us when we cancel a request, but I can't find anything about how URLSession handles cancellation. Is there a standard cancel-message over the protocol HTTP?
The client doesn’t send 499. Status codes are one-way. Rather, the client closes the network connection. The server records that dropped connection as a 499 status code in its logs.
If the server is HTTP/2 or later, the client may send either a END_STREAM or RST_STREAM message to cancel a single request without canceling other requests on the same connection, or it may just drop the connection. Either way, you’ll probably just see a 499 in your logs. There is little reason to care whether the connection was dropped or cancelled.

Server side notification when action cable disconnects

If you change a Rails application file (say a view), then you make a request on the server (i.e. API HTTP request) ActionCable drops any actioncable (websocket) connections.
The connection will be automatically re-established in about 7 seconds but if any messages are sent during this time they will be dropped.
Soooo the question is is there any way to get a notification on the server that the connection is being dropped? That way the server application can internally queue up messages until the connections are re-established.

First http request in iOS networking is slow, subsequent requests are much faster

I'm experiencing slow response times for my first http POST request to my server.
This happens both in Android and iOS networking libraries. (Volley on Android, and Alamofire in iOS).
First response is roughly 0.7s-0.9s, whereas subsequent requests are 0.2s.
I'm guessing this is due to the session being kept-alive by the server, therefore eliminating the need for establishing a new session on each request.
I figure I can make a dummy request when the app starts to start the session, but it doesn't seem very elegant.
I also control the server side (Node.js) so if any configuration needs to be done there I can also try it.
Investigating a little further, I tried sending an https CONNECT request before issuing the first "real" POST request, and the behavior replicates.
After 30 seconds or so, the connection is dropped (probably at the iOS URLSession level, the load balancer is configured to keep connections as 60 seconds).
In theory this makes sense because setting up an https connection takes up several (12 total) packets and I'm on an inter continental connection.
So my solution is to send a CONNECT request when I expect the user to send a regular request.

Http request (GET) timeout sometimes and I want to find the cause

I am developing an iOS app that makes an API request to my server hosted in Heroku.
In my slow internet connection environment, the API request (via Http Get) sometimes results in a timeout. The response time is usually 2000 ms if not timing out.
By "sometimes", I mean about one in 10 requests times out (I do not get any meaningful error code).
I also tested this timeout with 2 devices. When one device is waiting for the server to respond for longer than 2000 ms, I use another device to call the api, to which the server responds normally. But the first device still results in a timeout.
I am not quite sure what is to blame here. My internet connection? My api server on Heroku? I also tested this timeout on Postman and got the same results.
PS. I am based out of Bangkok. The ISP with which I experience the most timeouts is True Broadband.
Any and all advice is appreciated.
Thanks in advance
PPS. In response to comments warning that the question is too broad: Let's ask it this way. If our api calls randomly time out, how can we detect whether it is due to a slow internet connection, or if the fault lies in our own server (or something else)?

Resources