Skip to content

Commit 33c030d

Browse files
authored
Merge pull request #5776 from cloudflare/yagiz/fix-desiredSize
desiredSize should be null when the stream is erroring
2 parents 28f0816 + 8e5dd2e commit 33c030d

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

src/workerd/api/streams/standard.c++

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,9 @@ template <typename Self>
11301130
WritableImpl<Self>::WritableImpl(
11311131
jsg::Lock& js, WritableStream& owner, jsg::Ref<AbortSignal> abortSignal)
11321132
: owner(owner.addWeakRef()),
1133-
signal(kj::mv(abortSignal)) {}
1133+
signal(kj::mv(abortSignal)) {
1134+
flags.pedanticWpt = FeatureFlags::get(js).getPedanticWpt();
1135+
}
11341136

11351137
template <typename Self>
11361138
jsg::Promise<void> WritableImpl<Self>::abort(
@@ -3244,7 +3246,11 @@ void WritableStreamDefaultController::error(
32443246
impl.error(js, JSG_THIS, reason.orDefault(js.undefined()));
32453247
}
32463248

3247-
ssize_t WritableStreamDefaultController::getDesiredSize() {
3249+
kj::Maybe<ssize_t> WritableStreamDefaultController::getDesiredSize() {
3250+
// Per the spec, desiredSize should be null when the stream is erroring.
3251+
if (impl.flags.pedanticWpt && isErroring()) {
3252+
return kj::none;
3253+
}
32483254
return impl.getDesiredSize();
32493255
}
32503256

@@ -3403,7 +3409,7 @@ kj::Maybe<int> WritableStreamJsController::getDesiredSize() {
34033409
return kj::none;
34043410
}
34053411
KJ_CASE_ONEOF(controller, Controller) {
3406-
return controller->getDesiredSize();
3412+
return controller->getDesiredSize().map([](ssize_t size) -> int { return size; });
34073413
}
34083414
}
34093415
KJ_UNREACHABLE;
@@ -3416,6 +3422,10 @@ kj::Maybe<v8::Local<v8::Value>> WritableStreamJsController::isErroring(jsg::Lock
34163422
return kj::none;
34173423
}
34183424

3425+
bool WritableStreamDefaultController::isErroring() const {
3426+
return impl.state.is<StreamStates::Erroring>();
3427+
}
3428+
34193429
kj::Maybe<v8::Local<v8::Value>> WritableStreamJsController::isErroredOrErroring(jsg::Lock& js) {
34203430
KJ_IF_SOME(err, state.tryGet<StreamStates::Errored>()) {
34213431
return err.getHandle(js);

src/workerd/api/streams/standard.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ class WritableImpl {
385385
uint8_t started : 1 = 0;
386386
uint8_t starting : 1 = 0;
387387
uint8_t backpressure : 1 = 0;
388+
uint8_t pedanticWpt : 1 = 0;
388389
};
389390
Flags flags{};
390391

@@ -597,12 +598,17 @@ class WritableStreamDefaultController: public jsg::Object {
597598

598599
void error(jsg::Lock& js, jsg::Optional<v8::Local<v8::Value>> reason);
599600

600-
ssize_t getDesiredSize();
601+
kj::Maybe<ssize_t> getDesiredSize();
601602

602603
jsg::Ref<AbortSignal> getSignal();
603604

604605
kj::Maybe<v8::Local<v8::Value>> isErroring(jsg::Lock& js);
605606

607+
// Returns true if the stream is in the erroring state. Unlike the overload
608+
// that takes a lock, this method does not require a lock since it doesn't
609+
// return the error reason.
610+
bool isErroring() const;
611+
606612
bool isStarted() {
607613
return impl.flags.started;
608614
}

src/workerd/api/streams/writable.c++

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jsg::MemoizedIdentity<jsg::Promise<void>>& WritableStreamDefaultWriter::getClose
112112
return KJ_ASSERT_NONNULL(closedPromise, "the writer was never attached to a stream");
113113
}
114114

115-
kj::Maybe<int> WritableStreamDefaultWriter::getDesiredSize(jsg::Lock& js) {
115+
kj::Maybe<int> WritableStreamDefaultWriter::getDesiredSize() {
116116
KJ_SWITCH_ONEOF(state) {
117117
KJ_CASE_ONEOF(i, Initial) {
118118
KJ_FAIL_ASSERT("this writer was never attached");

src/workerd/api/streams/writable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class WritableStreamDefaultWriter: public jsg::Object, public WritableStreamCont
2323

2424
jsg::MemoizedIdentity<jsg::Promise<void>>& getClosed();
2525
jsg::MemoizedIdentity<jsg::Promise<void>>& getReady();
26-
kj::Maybe<int> getDesiredSize(jsg::Lock& js);
26+
kj::Maybe<int> getDesiredSize();
2727

2828
jsg::Promise<void> abort(jsg::Lock& js, jsg::Optional<v8::Local<v8::Value>> reason);
2929

src/wpt/streams-test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,11 +745,9 @@ export default {
745745
expectedFailures:
746746
process.platform === 'win32'
747747
? [
748-
'controller argument should be passed to start method',
749748
'WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure',
750749
]
751750
: [
752-
'controller argument should be passed to start method',
753751
'WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure',
754752
'underlyingSink argument should be converted after queuingStrategy argument',
755753
],
@@ -770,7 +768,6 @@ export default {
770768
'writable-streams/general.any.js': {
771769
comment: 'To be investigated',
772770
expectedFailures: [
773-
'desiredSize on a writer for an errored stream',
774771
"WritableStream's strategy.size should not be called as a method",
775772
'closed and ready on a released writer',
776773
'ready promise should fire before closed on releaseLock',

0 commit comments

Comments
 (0)