ninenines / gun

HTTP/1.1, HTTP/2, Websocket client (and more) for Erlang/OTP.
ISC License
891 stars 232 forks source link

Gun is missing an idle_timeout #254

Closed sanjuktaindia closed 1 year ago

sanjuktaindia commented 3 years ago

Hi, We would like to send the ping ack response to parent process. So that we can monitor successive pings and raise flag for connection fail. Please provide suggestions how we can achieve it?

essen commented 3 years ago

Gun already sends gun_down when the connection has failed. What would pings do extra in your case that gun_down doesn't do?

sanjuktaindia commented 3 years ago

Hello Loïc, Thanks for replying to my email. I don't want to wait for connection drop. With ping every 60s we want to monitor if the connection is up or down. Let's say for example: if pings fail we want to delete that connection and mark it as out of service and raise alarm. If 3 successful PINGs are successful we would like to mark it in service again and clear alarm. (It's more like I want to implement heartbeat mechanism by continues monitoring connection)

Please share your thoughts on this.

On Tue, 1 Dec 2020, 4:17 pm Loïc Hoguin, notifications@github.com wrote:

Gun already sends gun_down when the connection has failed. What would pings do extra in your case that gun_down doesn't do?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ninenines/cowboy/issues/1486#issuecomment-736396624, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIFXUTF2VZZZ6L26NM5BMD3SSTCSZANCNFSM4UI2D2WQ .

essen commented 3 years ago

OK that's a little clearer because what you showed by email was when the server sends a ping and we reply with a ping_ack, while what I think you're saying is you want to know when Gun has sent a ping and we receive a ping_ack.

But notifying ping_acks alone would not provide you with any insight because you don't know when the ping was sent.

What Gun is currently missing is an idle timeout where Gun does not use pings for determining whether the connection is still here, but rather any data coming through is an indication of the connection being up. So I'm not sure what you mean by waiting for the connection drop, if you ping every 60s you're unlikely to catch any issue because Gun will detect a problem within those 60s to begin with and close the connection.

zuiderkwast commented 2 years ago

Hi Loic,

we have a request from one of our product teams (a major Ericsson product) for a way to brutally close the connection if no ping ack (HTTP/2) is received after 3 pings. Currently, AFAICT ping_ack is just ignored, but I may have missed something.

I can imagine a configuration like keepalive_tolerance => NumPingsWithoutAck :: non_neg_integer(). This, together with the existing keepalive (milliseconds) option let's the user control this in a sufficiently granular way, I think.

Another way is by notifying the application about ping_ack_received as @sanjuktaindia suggested. In that case, we'd also need ping_sent to be sent to the application so it can keep track of when the ping is sent, as you commented. This gives full control to the application.

What do you think?

essen commented 2 years ago

When you say after 3 pings, does that mean the connection gets closed when it is time to send a 4th ping and no ping_ack has been received? In that case I can see the configuration working out. It doesn't supersede the idle_timeout option though since that one would be protocol-agnostic since it's at the socket level.

About notifying the application, I believe it is something that, if necessary, should be done via the event handlers, perhaps with a new callback notifying both ping and ping acks.

Whichever of the two options you decide on let's do that in a separate ticket/PR.

JeppeTh commented 2 years ago

Idle_timeout is rather about disconnecting idle connections (in cowboy at least)?

To determine if a non-idle connection is broken you don't need ping? Any request sent on the non-idle connection can be used for that?

essen commented 2 years ago

There's no real difference between a request and pings, as far as detecting broken connections go. If data goes in and out, the connection is working. Counting time between ping/ping_ack is the same as request/response, if you issue a request and don't get a response in time, you can drop the connection, you don't need to do a separate ping for that.

What ping does that everything else doesn't is help maintain connections open when the connection is otherwise idle.

essen commented 1 year ago

This was merged. Thanks!