beast icon indicating copy to clipboard operation
beast copied to clipboard

websockets: Count pings from server as activity for idle_timeout

Open xim opened this issue 1 year ago • 49 comments

If the stream is receiving control packets like ping, don't count it as idle. This means you can enable timeout_opt.keep_alive_ping on only one side to get heartbeat.

Addresses issue #2716

xim avatar Aug 11 '23 12:08 xim

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (e42cf8a) 93.03% compared to head (c8ffce2) 93.03%.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2718      +/-   ##
===========================================
- Coverage    93.03%   93.03%   -0.01%     
===========================================
  Files          178      178              
  Lines        13687    13684       -3     
===========================================
- Hits         12734    12731       -3     
  Misses         953      953              
Files Coverage Δ
include/boost/beast/websocket/impl/stream_impl.hpp 96.16% <100.00%> (-0.03%) :arrow_down:
include/boost/beast/websocket/stream_base.hpp 26.31% <ø> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update e42cf8a...c8ffce2. Read the comment docs.

codecov[bot] avatar Aug 11 '23 13:08 codecov[bot]

Can't this be configured already?

beast::websocket::stream_base::timeout to;
my_ws.get_option(to);
to.keep_alive_pings = true;
my_ws.set_option(to);

klemens-morgenstern avatar Aug 11 '23 13:08 klemens-morgenstern

This PR changes the behavior when keep_alive_ping is false.

Without the change: receiving control frames does not count as "activity"

With the change: receiving control frames counts as activity

I could make that behaviour change another config member of the timeout struct if wanted.

xim avatar Aug 11 '23 14:08 xim

I understand that - but why? Isn't setting the option achieving the same thing? What's the difference?

klemens-morgenstern avatar Aug 11 '23 14:08 klemens-morgenstern

Ah. The setting makes you send ping frames at an even interval. This change counts incoming control frames as activity regardless of whether or not you are sending pings yourself.

xim avatar Aug 11 '23 15:08 xim

Receiving control frames is not activity.

So we would need another option to allow the pings to be counted as such. This all seems off to me, why don't you just send pings or increase the timeout?

klemens-morgenstern avatar Aug 14 '23 10:08 klemens-morgenstern

I first reported this because I was confused by the idle_timeout / keep_alive_pings config options; Since a pong is activity when you've sent a ping, shouldn't a ping be activity as well?

If not, timely disconnect detection needs ping and pong to be sent in both directions, doubling the number of packets sent/received for no additional benefit.

Not a big issue, but I feel counting ping as activity is the more intuitive behaviour. Adding this as a bool incoming_ping_keepalives = false option also makes sense if keeping the old behaviour as default is a priority.

xim avatar Aug 14 '23 12:08 xim

Updated the PR with tests, @ashtum

I feel using a second wall clock time may be excessive, but seems to be somewhat in line with what other tests have done

xim avatar Aug 30 '23 12:08 xim

Can/should I add/change documentation somehow? Is it sufficient that I update the inline documentation in stream_base.hpp?

xim avatar Sep 01 '23 09:09 xim

Yes, please update the docs here as well (if there is anything related).

ashtum avatar Sep 01 '23 11:09 ashtum

@xim Anything I can help with?

ashtum avatar Sep 16 '23 09:09 ashtum

Sorry, @ashtum, this just disappeared in the Big Pile of Stuff. I'll try to update docs on Monday

xim avatar Sep 16 '23 10:09 xim

Apologies for forgetting about the documentation update. I rebased on develop, added documentation and pushed again.

xim avatar Oct 02 '23 07:10 xim

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 02 '23 07:10 cppalliance-bot

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 02 '23 09:10 cppalliance-bot

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 02 '23 10:10 cppalliance-bot

I'm happy with this now. If you want me to squash all commits, or fixup my fixup, or anything, just give the word =)

xim avatar Oct 02 '23 12:10 xim

This can be squashed on our side, this looks like a single commit.

From what I can tell @vinniefalco approves the behavioural change, so everything looks good to me.

klemens-morgenstern avatar Oct 04 '23 05:10 klemens-morgenstern

Looks like one of the tests has a timer that's 500ms and expects it to have been triggered after 600ms. I'll make it more permissive.

xim avatar Oct 04 '23 13:10 xim

Made that 750ms, effectively bumping the slack from 100ms to 250ms

xim avatar Oct 04 '23 13:10 xim

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 04 '23 13:10 cppalliance-bot

Apologies for the noise. Tweaking these values is hard.

xim avatar Oct 04 '23 14:10 xim

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 04 '23 14:10 cppalliance-bot

An automated preview of the documentation is available at https://2718.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Oct 04 '23 18:10 cppalliance-bot

@xim Why did you alter the timing values in the tests? Did you encounter any failures as a result of the tight timings?

ashtum avatar Oct 09 '23 06:10 ashtum

Yes. I had to increase/change margins many times before all the different CI builders were green at the same time. The original timing worked once across the board, but not on the next run. The current timing should be stable.

I'd love to see these tests run with stubbed time, for stability and execution speed. But don't know if that's readily available.

xim avatar Oct 09 '23 09:10 xim

Hey @xim, I wanted to let you know that I've decided to review and merge this after the 1.84 release. I reckon it might be risky to do it for 1.84.

ashtum avatar Nov 19 '23 17:11 ashtum

I have, for now, implemented most of the desired behaviour on top of the control callback. Looking forward to cleaning up that code ^_^

xim avatar Nov 19 '23 20:11 xim

Why shouldn't control frames count as activity?

vinniefalco avatar Nov 24 '23 12:11 vinniefalco

Why shouldn't control frames count as activity?

Did you mean, "Why should control frames count as activity?" If so, we had a discussion in https://github.com/boostorg/beast/issues/2716. The idea is that receiving any form of frame from the other side can be an indication that it is still active.

ashtum avatar Nov 24 '23 17:11 ashtum