perf(ext/websocket): optimize socket.send (#16320)

Towards #16315
This commit is contained in:
Divy Srivastava 2022-10-19 16:23:13 +05:30 committed by GitHub
parent 57f17bd3e6
commit 36307c45e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 143 additions and 28 deletions

View file

@ -18,20 +18,20 @@
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypeSome,
DataView,
ErrorPrototypeToString,
ObjectDefineProperties,
ObjectPrototypeIsPrototypeOf,
PromisePrototypeThen,
RegExpPrototypeTest,
Set,
String,
StringPrototypeEndsWith,
StringPrototypeToLowerCase,
Symbol,
SymbolIterator,
PromisePrototypeCatch,
queueMicrotask,
SymbolFor,
Uint8Array,
} = window.__bootstrap.primordials;
webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
@ -290,40 +290,58 @@
throw new DOMException("readyState not OPEN", "InvalidStateError");
}
if (typeof data === "string") {
// try to send in one go!
const d = core.byteLength(data);
const sent = ops.op_ws_try_send_string(this[_rid], data);
this[_bufferedAmount] += d;
if (!sent) {
PromisePrototypeThen(
core.opAsync("op_ws_send_string", this[_rid], data),
() => {
this[_bufferedAmount] -= d;
},
);
} else {
// Spec expects data to be start flushing on next tick but oh well...
// we already sent it so we can just decrement the bufferedAmount
// on the next tick.
queueMicrotask(() => {
this[_bufferedAmount] -= d;
});
}
return;
}
const sendTypedArray = (ta) => {
// try to send in one go!
const sent = ops.op_ws_try_send_binary(this[_rid], ta);
this[_bufferedAmount] += ta.byteLength;
PromisePrototypeThen(
core.opAsync("op_ws_send", this[_rid], {
kind: "binary",
value: ta,
}),
() => {
if (!sent) {
PromisePrototypeThen(
core.opAsync("op_ws_send_binary", this[_rid], ta),
() => {
this[_bufferedAmount] -= ta.byteLength;
},
);
} else {
// Spec expects data to be start flushing on next tick but oh well...
// we already sent it so we can just decrement the bufferedAmount
// on the next tick.
queueMicrotask(() => {
this[_bufferedAmount] -= ta.byteLength;
},
);
});
}
};
if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) {
PromisePrototypeThen(
data.slice().arrayBuffer(),
(ab) => sendTypedArray(new DataView(ab)),
);
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) {
sendTypedArray(new Uint8Array(data));
} else if (ArrayBufferIsView(data)) {
sendTypedArray(data);
} else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) {
sendTypedArray(new DataView(data));
} else {
const string = String(data);
const d = core.encode(string);
this[_bufferedAmount] += d.byteLength;
} else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) {
PromisePrototypeThen(
core.opAsync("op_ws_send", this[_rid], {
kind: "text",
value: string,
}),
() => {
this[_bufferedAmount] -= d.byteLength;
},
data.slice().arrayBuffer(),
(ab) => sendTypedArray(new Uint8Array(ab)),
);
}
}