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

quiche: implement per-event loop processing of buffered QUIC CHLOs #8891

Closed
wants to merge 13 commits into from
Closed

Conversation

bencebeky
Copy link
Contributor

@bencebeky bencebeky commented Nov 5, 2019

Description: add UdpListenerCallbacks::onReadReady() and call
quic::QuicDispatcher()::ProcessBufferedChlos() from
ActiveQuicListener::onReadReady() to enable delayed opening of sessions
with a per-event loop limit.

Fixes: #8756

Risk Level: low, not in use

Testing: UdpListenerImplTest is updated to test new onReadReady() calls.
EnvoyQuicDispatcherTest is updated to test that CHLOs are buffered.

Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Bence Béky [email protected]

Description: add UdpListenerCallbacks::onReadReady() and call
quic::QuicDispatcher()::ProcessBufferedChlos() from
ActiveQuicListener::onReadReady() to enable delayed opening of sessions
with a per-event loop limit.

Risk Level: low, not in use

Testing: UdpListenerImplTest is updated to test new onReadReady() calls.
EnvoyQuicDispatcherTest is updated to test that CHLOs are buffered.

Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Bence Béky <[email protected]>
@bencebeky
Copy link
Contributor Author

/assign danzh2010

@bencebeky
Copy link
Contributor Author

@danzh2010 The EnvoyQuicDispatcherTest tests EnvoyQuicDispatcher's behavior as far as ProcessPacket() and ProcessBufferedChlos() is concerned. However, I should also test that a new event loop calls ProcessBufferedChlos(). This has to be a ActiveQuicListenerTest. However, I do not see any packets buffered, see https://github.com/envoyproxy/envoy/pull/8891/files#diff-6a27a42427472c010c1a55f272fa72f4. Please help.

@danzh2010
Copy link
Contributor

However, I do not see any packets buffered, see https://github.com/envoyproxy/envoy/pull/8891/files#diff-6a27a42427472c010c1a55f272fa72f4.

It will start bufferring after receiving more than kNumSessionsToCreatePerEpollForTests CHLO's in one epoll loop.

@danzh2010
Copy link
Contributor

Is this ready for review?

@bencebeky
Copy link
Contributor Author

kNumSessionsToCreatePerEpollForTests

I'm still confused. The event loop is only run once in ActiveQuicListenerTest.ReceiveFullQuicCHLO. ProcessBufferedChlos() is called before any reads, when there are no CHLOs buffered. I can verify this by calling ASSERT(!quic_dispatcher_->HasChlosBuffered()); right above the ProcessBufferedChlos() call in ActiveQuicListener::onReadReady(), and the test still passes. Then QuicDispatcher should buffer the CHLO instead of processing it, and it should only be processed in the next event loop. But this is not what happens. What am I overlooking?

@bencebeky
Copy link
Contributor Author

@danzh2010 gave me direction offline. The ball is now in my court.

/wait

Signed-off-by: Bence Béky <[email protected]>
Signed-off-by: Bence Béky <[email protected]>
@bencebeky
Copy link
Contributor Author

@danzh2010 gave me direction offline. The ball is now in my court.

/wait

Finally all checks have passed, this is now ready for review.

Copy link
Contributor

@danzh2010 danzh2010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

include/envoy/network/listener.h Show resolved Hide resolved
}
ConfigureMocks(/* connection_count = */ 1);
GenerateCHLO(quic::test::TestConnectionId(1));
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would NonBlock here cause data race where data arrives after we exit the loop? Can we still use Block and exit() instead? Actually this test maybe by nature flaky because we can't guarantee that the 16 CHLOs arrive in one event loop. Can you test with --runs_per_test to see if it flakes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I do not understand the event loop well enough to be able to tell if data could possibly arrive after we exit the loop. If you think it is possible, I could use Block and exit().

I also cannot say if this test could be flaky. If you think it is possible, then we could lower the buffered CHLO limit to 1 and feed 2, that would be an improvement because 2 must have a better chance to arrive in the same event loop than 16.

Copy link
Contributor

@danzh2010 danzh2010 Nov 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try --runs_per_test to see if it's flaky first? My understanding about NonBlock is to run one loop and exit. If there is no active IO events, that's it.

Lowering the limit sounds reasonable. But again let's make sure the test doesn't flake in all builds before check in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I am not able to run this test locally. It crashes with segmentation fault. Both direct bazel and when using a docker container. Does the same on HEAD.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NonBlock guarantees that the event loop will only be run once. Otherwise all CHLOs would be processed, because the limit kNumSessionsToCreatePerEpoll is per event loop. Also Block would require calling exit() from the last read_filter.onNewConnection() mock call but not from earlier ones, which is certainly doable but seems to add complexity unnecessarily to test code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that Block and exit() doesn't satisfy our need. Are we sure that there is no race between receiving the packet and dispatcher.run() now?

@stale
Copy link

stale bot commented Nov 28, 2019

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Nov 28, 2019
@bencebeky
Copy link
Contributor Author

I'm unblocked now that #8999 got merged, adding MockIoHandle that I should use in the test to mock out network sockets.

@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Nov 28, 2019
@stale
Copy link

stale bot commented Dec 10, 2019

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Dec 10, 2019
@stale
Copy link

stale bot commented Dec 17, 2019

This pull request has been automatically closed because it has not had activity in the last 14 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot closed this Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale stalebot believes this issue/PR has not been touched recently
Projects
None yet
Development

Successfully merging this pull request may close these issues.

quiche: re-enable packet buffering at QuicDispatcher
3 participants