watch: Reproduce the deadlock between in-process client-server due to cancellation storm#21064
watch: Reproduce the deadlock between in-process client-server due to cancellation storm#21064zhijun42 wants to merge 7 commits into
Conversation
Signed-off-by: Zhijun <dszhijun@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: zhijun42 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @zhijun42. Thanks for your PR. I'm waiting for a github.com member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
Signed-off-by: Zhijun <dszhijun@gmail.com>
Signed-off-by: Zhijun <dszhijun@gmail.com>
Signed-off-by: Zhijun <dszhijun@gmail.com>
Signed-off-by: Zhijun <dszhijun@gmail.com>
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions. |
|
I can't reopen this PR. Hopefully it can get reopened after the corresponding fix PR #21065 gets attention. |
Reproduces issues #18879 and #20716
The next PR #21065 properly solves these issues.
These two issues have the same root cause, and it only shows up with the in-process client–server path, not with a regular gRPC connection. Over the network, HTTP/2 flow control and socket teardown naturally apply backpressure and reset state, but the in-process transport is using the
chanStreaminserver/proxy/grpcproxy/adapter/chan_stream.go, which simply relies on go channels.When we have a lot of watch cancel requests, we would easily run into deadlock. Refer to #20716 for a nice diagram analyzing the deadlock.
Conceptually, each watch stream should be owned by a single client: if we rerun the program, we should expect to start from a clean slate. Unfortunately, with the in-process design there are effectively two layers of clients:
Rerunning the user program doesn’t reset the in-process client, so the connection between this in-process client and the server is still stuck in deadlock, and all subsequent user reruns would also be stuck (as long as these user programs rely on this in-process client, but notice that if you do
etcdctlor other programs that can directly talk to the etcd server, you can still use the watch feature without problem).This PR adds an integration test to reproduce this issue. It creates a lot of watchers, ensures they work fine at first, and then cancels most of these watchers. The remaining watchers stop receiving any watch events, and we will see non-zero
etcd_debugging_mvcc_slow_watcher_totalandetcd_debugging_mvcc_pending_events_totalmetrics.