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

Convert DigestStream into JS-backed stream #2050

Merged
merged 1 commit into from May 15, 2024

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented Apr 23, 2024

This is one of a series of PRs intended to simplify and improve the implementation/safety/performance/design of various streams bits in the runtime. This one starts with refactoring DigestStream.
 
The original implementation of DigestStream used a WritableStreamSink and the old "internal" streams implementation. This is unnecessary and makes the implementation less efficient than it otherwise could be due to the operations having to bounce between the kj event loop and the JS isolate lock. There's just nothing in the implementation of DigestStream that requires the bound through the kj event loop and the original implementation was more an artifact of what was possible at the time it was written.

This PR converts DigestStream into a JS-backed stream where the operations occur within the isolate lock. Also avoids the need for IoContext addObject / IoOwn dereferencing. Implementation should be generally safer and more efficient.

Also...

  • allow DigestStream to accept string inputs. If a string is written to a DigestStream, it will be converted to UTF-8 bytes and included in the digest.
  • allow DigestStream to support Symbol.dispose.
  • adds a new bytesWritten property to DigestStream to allow for checking to make sure the digest received the expected number of bytes.
  • Improves tests a bit

Internal CI is green.

@jasnell jasnell requested review from a team as code owners April 23, 2024 23:46
@jasnell jasnell force-pushed the jsnell/refactor-digeststream branch from 5819b0c to 618ba24 Compare April 24, 2024 00:28
@jasnell jasnell added the api label Apr 26, 2024
jasnell added a commit that referenced this pull request Apr 26, 2024
removeSink is used to extract the WritableStreamSink that is owned by
a WritableStream using the original implementation. It is currently
used in only two places in the codebase, neither of which are necessary.
There are two pending changes refactoring those two places to avoid
using `removeSink()` as currently defined. Replacing the version of
`removeSink` that returns the `WritableStreamSink` with a `detach()`
method that returns nothing covers the sockets use case where we call
the method then immediately throw away the sink.

Once this and the two other PRs land, we can safely remove removeSink
entirely.

Refs: #2061
Refs: #2050
jasnell added a commit that referenced this pull request Apr 26, 2024
removeSink is used to extract the WritableStreamSink that is owned by
a WritableStream using the original implementation. It is currently
used in only two places in the codebase, neither of which are necessary.
There are two pending changes refactoring those two places to avoid
using `removeSink()` as currently defined. Replacing the version of
`removeSink` that returns the `WritableStreamSink` with a `detach()`
method that returns nothing covers the sockets use case where we call
the method then immediately throw away the sink.

Once this and the two other PRs land, we can safely remove removeSink
entirely.

Refs: #2061
Refs: #2050
jasnell added a commit that referenced this pull request May 1, 2024
removeSink is used to extract the WritableStreamSink that is owned by
a WritableStream using the original implementation. It is currently
used in only a few places in the codebase, none of which are necessary.
There are two pending changes refactoring those two places to avoid
using `removeSink()` as currently defined. Replacing the version of
`removeSink` that returns the `WritableStreamSink` with a `detach()`
method that returns nothing covers the sockets use case where we call
the method then immediately throw away the sink.

Once this and the other PRs land, we can safely remove removeSink
entirely.

Refs: #2061
Refs: #2050
Refs: #2066
@jasnell jasnell requested a review from dom96 May 3, 2024 21:42
Copy link
Collaborator

@dom96 dom96 left a comment

Choose a reason for hiding this comment

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

It would be nice to put this behind an autogate... but I can see that would be tough. I wonder if we should try to get the oncall to roll this out in a separate release at least.

src/workerd/api/crypto.c++ Show resolved Hide resolved
src/workerd/api/crypto.c++ Outdated Show resolved Hide resolved
@jasnell
Copy link
Member Author

jasnell commented May 8, 2024

autogate would be a lot more complicated. I'm the oncall next week so I can easily use one of the daily releases to roll this out in isolation.

@jasnell jasnell force-pushed the jsnell/refactor-digeststream branch 2 times, most recently from d53bea1 to 49cf25e Compare May 8, 2024 16:46
@jasnell
Copy link
Member Author

jasnell commented May 8, 2024

This is ready to go, I'm just going to hold off merging until next week in order to have a dedicated internal release for it.

The original implementation of `DigestStream` used a WritableStreamSink
and the old "internal" streams implementation. This is unnecessary and
makes the implementation less efficient that it otherwise could be due
to the operations having to bounce between the kj event loop and the
JS isolate lock. This change converts `DigestStream` into a JS-backed
stream where the operations occur within the isolate lock, avoiding
the bounce and avoiding having to reacquire the isolate lock after
each chunk, etc. Also avoids the need for IoContext addObject / IoOwn
dereferencing. Implementation should be safer and more efficient.

Also allow DigestStream to accept string inputs. If a string is written
to a DigestStream, it will be converted to UTF-8 bytes and included in
the digest.

Also allow DigestStream to support `Symbol.dispose`.

Improves tests a bit also.
@jasnell jasnell force-pushed the jsnell/refactor-digeststream branch from 49cf25e to 97cd544 Compare May 15, 2024 13:47
@jasnell jasnell merged commit 9bfce12 into main May 15, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants