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

QUIC stream limits #52704

Merged
merged 24 commits into from
Jun 6, 2021
Merged

QUIC stream limits #52704

merged 24 commits into from
Jun 6, 2021

Conversation

ManickaP
Copy link
Member

@ManickaP ManickaP commented May 13, 2021

Implements the 3rd option Allowing the caller to perform their own wait from #32079 (comment)

  • Adds WaitForAvailable(Bidi|Uni)rectionalStreamsAsync:
    • triggered by peer announcement about new streams (QUIC_CONNECTION_EVENT_TYPE.STREAMS_AVAILABLE)
    • if the connection is closed/disposed, the method throws QuicConnectionAbortedException which fitted our H3 better than boolean (can be changed)
  • Makes Open(Bidi|Uni)directionalStreamAsync:
    • asynchronous, awaiting msquic event QUIC_STREAM_EVENT_TYPE.START_COMPLETE
    • throwing if there's no stream capacity QUIC_STREAM_START_FLAGS.FAIL_BLOCKED
    • immediately notifying the peer about stream being opened QUIC_STREAM_START_FLAGS.IMMEDIATE
  • Changes stream limit type to int

Fixes #32079

Note: working on adding more tests, opening PR to kick off discussion.

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented May 13, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Implements the 3rd option Allowing the caller to perform their own wait from #32079 (comment)

  • Adds WaitForAvailable(Bidi|Uni)rectionalStreamsAsync:
    • triggered by peer announcement about new streams (QUIC_CONNECTION_EVENT_TYPE.STREAMS_AVAILABLE)
    • if the connection is closed/disposed, the method throws QuicConnectionAbortedException which fitted our H3 better than boolean (can be changed)
  • Makes Open(Bidi|Uni)directionalStreamAsync:
    • asynchronous, awaiting msquic event QUIC_STREAM_EVENT_TYPE.START_COMPLETE
    • throwing if there's no stream capacity QUIC_STREAM_START_FLAGS.FAIL_BLOCKED
    • immediately notifying the peer about stream being opened QUIC_STREAM_START_FLAGS.IMMEDIATE
  • Changes stream limit type to int

Fixes #32079

Note: working on adding more tests, opening PR to kick off discussion.

Author: ManickaP
Assignees: -
Labels:

area-System.Net.Quic, new-api-needs-documentation

Milestone: -

@geoffkizer
Copy link
Contributor

immediately notifying the peer about stream being opened QUIC_STREAM_START_FLAGS.IMMEDIATE

Why do this? Seems like this would be bad for H3 perf.

public long GetRemoteAvailableUnidirectionalStreamCount() { throw null; }
public System.Net.Quic.QuicStream OpenBidirectionalStream() { throw null; }
public System.Net.Quic.QuicStream OpenUnidirectionalStream() { throw null; }
public int GetRemoteAvailableBidirectionalStreamCount() { throw null; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why was this changed? Is it limited to int.Max by QUIC itself?

Copy link
Member Author

@ManickaP ManickaP May 24, 2021

Choose a reason for hiding this comment

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

Msquic returns ushort:

internal override long GetRemoteAvailableUnidirectionalStreamCount()
{
return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_UNIDI_STREAM_COUNT);
}
internal override long GetRemoteAvailableBidirectionalStreamCount()
{
return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_BIDI_STREAM_COUNT);
}

AFAIK, we usually go with signed types for APIs ==> int.

I'm aware that QUIC sends long-range values in MAX_STREAMS frame, but that's cumulative number of streams which msquic hides from us. This is probably the original motivation for the long type.

Once again, I'm not against keeping it long. We discussed it briefly in one of our meetings and the consensus was for int so I went ahead with the change.

@@ -53,6 +53,56 @@ public async Task UnidirectionalAndBidirectionalChangeValues()
Assert.Equal(20, serverConnection.GetRemoteAvailableUnidirectionalStreamCount());
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/52048")]
Copy link
Member Author

Choose a reason for hiding this comment

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

These 2 new tests pass on their own but if run within the whole suite they cause the crash with stream being finalized after the connection. That should be fixed with #52800, I'll revisit it enabling them afterwards.

Copy link
Member

Choose a reason for hiding this comment

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

We discussed offline that it is caused by not accepted stream getting stuck inside accept queue and not being disposed there. You can try accepting it (after all test checks if it's important for the test) and disposing manually, or you may wait for Tomas' fix, your choice.

@ManickaP ManickaP requested a review from geoffkizer May 27, 2021 08:30
@ManickaP ManickaP force-pushed the mapichov/32079_stream_limit branch from ff29d76 to df0d529 Compare May 28, 2021 14:47
@ManickaP ManickaP force-pushed the mapichov/32079_stream_limit branch 2 times, most recently from 653c080 to 6609348 Compare June 1, 2021 17:38
@ManickaP ManickaP force-pushed the mapichov/32079_stream_limit branch 2 times, most recently from 544bea4 to cabc0eb Compare June 2, 2021 15:43
@ManickaP ManickaP force-pushed the mapichov/32079_stream_limit branch from cabc0eb to 719df10 Compare June 3, 2021 14:28
@CarnaViire
Copy link
Member

LGTM, waiting on test cleanup and resolving a question about two locks vs one

@ManickaP
Copy link
Member Author

ManickaP commented Jun 3, 2021

I moved the experiments with the failing test into its own branch and disabled it in this PR (with an ActiveIssue).
Everything should be cleaned up a addressed now. Only waiting for a final review.

Copy link
Member

@CarnaViire CarnaViire left a comment

Choose a reason for hiding this comment

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

LGTM, but it would be great if @scalablecory or @geoffkizer could also take a look.

@ManickaP ManickaP force-pushed the mapichov/32079_stream_limit branch from 9ea99fa to 7eb7fb1 Compare June 4, 2021 18:20
@ManickaP ManickaP merged commit a822d39 into dotnet:main Jun 6, 2021
@ManickaP ManickaP deleted the mapichov/32079_stream_limit branch June 6, 2021 11:08
@ManickaP ManickaP mentioned this pull request Jun 7, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jul 6, 2021
@karelz karelz added this to the 6.0.0 milestone Jul 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[QUIC] Decide how to handle QUIC stream limits
4 participants