Skip to content
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

Make it possible to disable heartbeats #467

Closed
carlhoerberg opened this issue Oct 16, 2018 · 11 comments · May be fixed by #469
Closed

Make it possible to disable heartbeats #467

carlhoerberg opened this issue Oct 16, 2018 · 11 comments · May be fixed by #469

Comments

@carlhoerberg
Copy link
Contributor

carlhoerberg commented Oct 16, 2018

It's currently not possible to disable heartbeats, if you set a heartbeat value of 0 on the client side it will use the server's suggested value instead of disabling it (sending 0 to the server in the TuneOk frame).

https://github.com/squaremo/amqp.node/blob/6ee18f27e31863f5256bc921a21f36ebf2ba5e74/lib/connection.js#L192-L198

@carlhoerberg
Copy link
Contributor Author

@squaremo
Copy link
Collaborator

if you set a heartbeat value of 0 on the client side it will use the server's suggested value instead of disabling it

That's what it's supposed to do. See Matthias's explanation in #83.

@carlhoerberg
Copy link
Contributor Author

carlhoerberg commented Oct 16, 2018 via email

@squaremo
Copy link
Collaborator

Since you were so convinced that the server will accept a veto of heartbeats, I went to look at the server code:
https://github.com/rabbitmq/rabbitmq-server/blame/master/src/rabbit_reader.erl#L1166
.. and it's been like that since it was imported into git, at least:
https://github.com/rabbitmq/rabbitmq-common/blame/7caafeb817e3b8f2c8f026dfcd73343930c24e31/src/rabbit_reader.erl#L1116

The spec is not a great guide, but for the heartbeat field it does say (merely):

The delay, in seconds, of the connection heartbeat that the client wants. Zero means the client does not want a heartbeat.

Compare with, for example, the guidance for frame-max:

If the client specifies a frame max that is higher than the value provided by the server, the server MUST close the connection without attempting a negotiated close.

I'm compelled to conclude that the comments in #83 were misinterpreted -- they apply to channel-max and frame-max, but not to heartbeat, at least for RabbitMQ (I'm not going to go look at any other server code!).

@noorulcompro
Copy link

@squaremo @carlhoerberg

Hi Guys,

What's the conclusion? Can the client get option to disable the heartbeat?

@robross0606
Copy link

robross0606 commented Apr 4, 2022

RabbitMQ clearly states that a client should be able to disable heartbeats by setting the configuration value to 0:

Heartbeats can be disabled by setting the timeout interval to 0 on the client side at connection time.

https://www.rabbitmq.com/heartbeats.html#disabling

@cressie176
Copy link
Collaborator

cressie176 commented Apr 5, 2022

@robross0606,

It looks to me like the documentation you linked to contradicts itself. A little higher up it also states

A zero value indicates that a peer suggests disabling heartbeats entirely. To disable heartbeats, both peers have to opt in and use the value of 0.

I'm unfamiliar with erlang, but the server code this appears to confirm this is what was implemented...

tune(#'connection.tune'{channel_max = ServerChannelMax,
                        frame_max   = ServerFrameMax,
                        heartbeat   = ServerHeartbeat},
     #amqp_params_network{channel_max = ClientChannelMax,
                          frame_max   = ClientFrameMax,
                          heartbeat   = ClientHeartbeat}, State) ->
    [ChannelMax, Heartbeat, FrameMax] =
        lists:zipwith(fun (Client, Server) when Client =:= 0; Server =:= 0 ->
                              lists:max([Client, Server]);
                          (Client, Server) ->
                              lists:min([Client, Server])
                      end,
                      [ClientChannelMax, ClientHeartbeat, ClientFrameMax],
                      [ServerChannelMax, ServerHeartbeat, ServerFrameMax]),

If I interpret the above correctly, when either or both the client and server value are zero, then the maximum of the two will be used, otherwise the minimum value will be used. i.e.

client server calculation result
0 0 max(0, 0) 0
1 0 max(1, 0) 1
0 1 max(0, 1) 1
1 2 min(1, 2) 1
2 1 min(2, 1) 1

So the only way to disable heartbeats is by setting both the client and server to zero. For interest, the same issue was reported with the erlang client, and they reached the same conclusion.

@robross0606
Copy link

Sheesh, you’d think they would have updated and clarified the documentation by now if this is something so legacy that it cannot be changed in code. 😑

@cressie176
Copy link
Collaborator

I agree. I've raised the following rabbitmq/rabbitmq-website#1386

Going to close this as the behaviour is out of amqplibs' control

@lukebakken
Copy link

Sheesh, you’d think they would have updated and clarified the documentation by now if this is something so legacy that it cannot be changed in code.

@robross0606 perhaps it was just overlooked. The RabbitMQ docs are open-source so there is plenty of opportunity for users to contribute.

@carlhoerberg
Copy link
Contributor Author

amqp-client.js implements this pragmatically, set to zero on the client side means disable it. And amqp-client.js of course enables TCP keepalive, which is a much more reliable keepalive mechanism than AMQP heartbeats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants