Skip to content

Ensure HTTP/2 connections are gracefully closed on async cancellation - #757

Closed
karpetrosyan wants to merge 10 commits into
encode:masterfrom
karpetrosyan:fix-http2-cancellations-test
Closed

Ensure HTTP/2 connections are gracefully closed on async cancellation#757
karpetrosyan wants to merge 10 commits into
encode:masterfrom
karpetrosyan:fix-http2-cancellations-test

Conversation

@karpetrosyan

@karpetrosyankarpetrosyan commented Jul 14, 2023

Copy link
Copy Markdown
Contributor

Closes#756

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

TODO

  • Add failing tests
  • Gracefully handle cancellation for unstarted http/2 requests
  • Update changelog

@karpetrosyan
karpetrosyan requested a review from a teamJuly 14, 2023 09:22
@karpetrosyankarpetrosyan added bug Something isn't working tests Tests & coverage labels Jul 14, 2023
Comment threadhttpcore/_async/http2.py
Comment threadCHANGELOG.md Outdated
@karpetrosyankarpetrosyan changed the title Handle failed HTTP/2 requests gracefullyEnsure HTTP/2 connections are gracefully closed on cancellationJul 15, 2023

@T-256T-256 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could (async )with self._state_lock: move under _state_housekeeping function?

@zanieb

Copy link
Copy Markdown
Contributor

could (async )with self._state_lock: move under _state_housekeeping function?

I agree, it's always used.

@karpetrosyankarpetrosyan mentioned this pull request Aug 1, 2023
1 task
@lovelydinosaur

lovelydinosaur commented Aug 1, 2023

Copy link
Copy Markdown
Contributor

At thanks! The failing test case is especially helpful here.

Pretty sure this resolution is overcomplicated, tho. I think we actually want here is?...

  1. This existing try...except needs to be expanded...

try:
kwargs= {"request": request}
asyncwithTrace("send_connection_init", logger, request, kwargs):
awaitself._send_connection_init(**kwargs)
exceptBaseExceptionasexc:
withAsyncShieldCancellation():
awaitself.aclose()
raiseexc

...so that it instead covers all of this block...

try:
kwargs= {"request": request}
asyncwithTrace("send_connection_init", logger, request, kwargs):
awaitself._send_connection_init(**kwargs)
exceptBaseExceptionasexc:
withAsyncShieldCancellation():
awaitself.aclose()
raiseexc
self._sent_connection_init=True
# Initially start with just 1 until the remote server provides
# its max_concurrent_streams value
self._max_streams=1
local_settings_max_streams= (
self._h2_state.local_settings.max_concurrent_streams
)
self._max_streams_semaphore=AsyncSemaphore(local_settings_max_streams)
for_inrange(local_settings_max_streams-self._max_streams):
awaitself._max_streams_semaphore.acquire()

ie. the except case to move down to line 127 there.

  1. This call to acquire()...

awaitself._max_streams_semaphore.acquire()

Should also be surrounded with...

try:
awaitself._max_streams_semaphore.acquire()
exceptBaseExceptionasexc: withAsyncShieldCancellation(): awaitself.aclose() raiseexc

We could actually avoid (1) if we instead addressed the refactoring suggested in #738or refactored self._send_connection_init(**kwargs) so that our initial handshake waits for the settings response before we instantiate our max_streams_semaphore. But let's not be getting into that just now.

@lovelydinosaur

Copy link
Copy Markdown
Contributor

Ugh. I need to think about this one more clearly, it's making my brain mush.

@lovelydinosaurlovelydinosaur changed the title Ensure HTTP/2 connections are gracefully closed on cancellationEnsure HTTP/2 connections are gracefully closed on async cancellationAug 3, 2023
@karpetrosyan

Copy link
Copy Markdown
ContributorAuthor

I would recommend using this stupid solution for the time being and not waiting for http/2 refactoring from #770

@karpetrosyan
karpetrosyan requested a review from a teamAugust 28, 2023 06:20
@stale

staleBot commented Apr 26, 2025

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stalestaleBot added the wontfix This will not be worked on label Apr 26, 2025
@stalestaleBot closed this Jun 27, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't workingtestsTests & coveragewontfixThis will not be worked on

Development

Successfully merging this pull request may close these issues.

Ensure HTTP/2 connections are gracefully closed on async cancellation

4 participants

@karpetrosyan@zanieb@lovelydinosaur@T-256