Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Small tweaks to PipeReader behaviors#27596

Merged
davidfowl merged 2 commits intodotnet:masterfrom
davidfowl:master
Mar 1, 2018
Merged

Small tweaks to PipeReader behaviors#27596
davidfowl merged 2 commits intodotnet:masterfrom
davidfowl:master

Conversation

@davidfowl
Copy link
Member

  • Throw if AdvanceTo is called after completing the reader
  • Don't throw if Complete is called without AdvanceTo
  • Swapped the reading and writing exceptions
  • Added AdvanceReader that takes BufferSegment and int, this cleans up
    the API a bit as we touch SequencePosition in less places.

Fixes https://github.com/dotnet/corefx/issues/27467 and https://github.com/dotnet/corefx/issues/27465

- Throw if AdvanceTo is called after completing the reader
- Don't throw if Complete is called without AdvanceTo
- Swapped the reading and writing exceptions
- Added AdvanceReader that takes BufferSegment and int, this cleans up
the API a bit as we touch SequencePosition in less places.
@davidfowl davidfowl requested a review from pakrym March 1, 2018 07:01
_readingState.End();
}

// REVIEW: We should consider cleaning up all of the allocated memory
Copy link

Choose a reason for hiding this comment

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

I was intending to do something like this for a long time, the biggest problem is the producer that may continue writing after reader completed, so we don't want to return everything but keep a single segment around to return to the writer over and over again.

Copy link

Choose a reason for hiding this comment

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

How do we currently handle backpressure after reader completion?

Copy link
Member Author

Choose a reason for hiding this comment

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

We signal the writer with IsCompleted true when the reader completes.

Copy link

Choose a reason for hiding this comment

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

What if it keeps writing? We'll just expand the pipe forever?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. That's the case today right? This doesn't fix any problems there. I originally made this thing auto advance but there's no point because if you do call advance and you consume nothing, you're in the same boat.

This line of code is supposed to handle the case where the reader is completed:

https://github.com/davidfowl/corefx/blob/4dcaa60893740a2c7a934af9185d6a5cff62699b/src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs#L238

I'll add a test that does the following:

  1. Writes until there's backpressure
  2. Complete the reader
  3. Write again, awaitable returned should be completed since there's nobody to drain.

ReadResult result = await _pipe.Reader.ReadAsync();
ReadOnlySequence<byte> buffer = result.Buffer;

_pipe.Reader.Complete();
Copy link

Choose a reason for hiding this comment

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

Does the pipe get reset correctly after this?

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you mean? Are you asking if Reset works correctly if I complete both sides where the reader never called Advance? I can add a test for that.

Copy link

Choose a reason for hiding this comment

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

Yes exactly that scenario

@pakrym
Copy link

pakrym commented Mar 1, 2018

Add default threshold here too.

@davidfowl
Copy link
Member Author

Add default threshold here too.

I'm not doing that in this change.

@davidfowl
Copy link
Member Author

@pakrym added more tests

AvailableMemory = default;
}

internal OwnedMemory<byte> OwnedMemory => _ownedMemory;
Copy link

Choose a reason for hiding this comment

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

You could've used AvailableMemory == default instead exposing OM

Copy link
Member Author

Choose a reason for hiding this comment

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

How?


var startSegment = (BufferSegment)start;
var endSegment = (BufferSegment)end;
Assert.NotNull(startSegment.OwnedMemory);
Copy link

Choose a reason for hiding this comment

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

Assert.NotEqual(default(Memory<byte>), startSegment.AvailableMemory)

Copy link
Member Author

Choose a reason for hiding this comment

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

Meh, I don't trust it 😄

Copy link

Choose a reason for hiding this comment

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

It gets reset on the next line that the OM does.

@davidfowl davidfowl merged commit c6018ef into dotnet:master Mar 1, 2018
@karelz karelz added this to the 2.1.0 milestone Mar 10, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Small tweaks to PipeReader behaviors
- Throw if AdvanceTo is called after completing the reader
- Don't throw if Complete is called without AdvanceTo
- Swapped the reading and writing exceptions
- Added AdvanceReader that takes BufferSegment and int, this cleans up
the API a bit as we touch SequencePosition in less places.



Commit migrated from dotnet/corefx@c6018ef
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants