mirror of
https://github.com/denoland/deno.git
synced 2024-12-27 01:29:14 -05:00
refactor: migrate async ops to generated wrappers (#18937)
Migrates some of existing async ops to generated wrappers introduced in https://github.com/denoland/deno/pull/18887. As a result "core.opAsync2" was removed. I will follow up with more PRs that migrate all the async ops to generated wrappers.
This commit is contained in:
parent
3d0b879c0d
commit
016b43441b
10 changed files with 109 additions and 99 deletions
|
@ -564,31 +564,6 @@ for (let i = 0; i < 10; i++) {
|
||||||
return (ops[opName] = fn);
|
return (ops[opName] = fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
function opAsync2(name, arg0, arg1) {
|
|
||||||
const id = nextPromiseId++;
|
|
||||||
try {
|
|
||||||
const maybeResult = asyncOps[name](id, arg0, arg1);
|
|
||||||
if (maybeResult !== undefined) {
|
|
||||||
movePromise(id);
|
|
||||||
return unwrapOpResultNewPromise(id, maybeResult, opAsync2);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
movePromise(id);
|
|
||||||
if (!ReflectHas(asyncOps, name)) {
|
|
||||||
return PromiseReject(new TypeError(`${name} is not a registered op`));
|
|
||||||
}
|
|
||||||
ErrorCaptureStackTrace(err, opAsync2);
|
|
||||||
return PromiseReject(err);
|
|
||||||
}
|
|
||||||
let promise = PromisePrototypeThen(
|
|
||||||
setPromise(id),
|
|
||||||
unwrapOpError(eventLoopTick),
|
|
||||||
);
|
|
||||||
promise = handleOpCallTracing(name, id, promise);
|
|
||||||
promise[promiseIdSymbol] = id;
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
function opAsync(name, ...args) {
|
function opAsync(name, ...args) {
|
||||||
const id = nextPromiseId++;
|
const id = nextPromiseId++;
|
||||||
try {
|
try {
|
||||||
|
@ -823,7 +798,6 @@ for (let i = 0; i < 10; i++) {
|
||||||
asyncStub,
|
asyncStub,
|
||||||
generateAsyncOpHandler,
|
generateAsyncOpHandler,
|
||||||
opAsync,
|
opAsync,
|
||||||
opAsync2,
|
|
||||||
resources,
|
resources,
|
||||||
metrics,
|
metrics,
|
||||||
registerErrorBuilder,
|
registerErrorBuilder,
|
||||||
|
|
|
@ -3,7 +3,16 @@
|
||||||
// then write this fixed 'responseBuf'. The point of this benchmark is to
|
// then write this fixed 'responseBuf'. The point of this benchmark is to
|
||||||
// exercise the event loop in a simple yet semi-realistic way.
|
// exercise the event loop in a simple yet semi-realistic way.
|
||||||
|
|
||||||
const { ops, opAsync, opAsync2 } = Deno.core;
|
// deno-lint-ignore-file camelcase
|
||||||
|
|
||||||
|
const { op_listen } = Deno.core.ops;
|
||||||
|
const {
|
||||||
|
op_accept,
|
||||||
|
op_read_socket,
|
||||||
|
} = core.generateAsyncOpHandler(
|
||||||
|
"op_accept",
|
||||||
|
"op_read_socket",
|
||||||
|
);
|
||||||
|
|
||||||
const requestBuf = new Uint8Array(64 * 1024);
|
const requestBuf = new Uint8Array(64 * 1024);
|
||||||
const responseBuf = new Uint8Array(
|
const responseBuf = new Uint8Array(
|
||||||
|
@ -12,24 +21,10 @@ const responseBuf = new Uint8Array(
|
||||||
.map((c) => c.charCodeAt(0)),
|
.map((c) => c.charCodeAt(0)),
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Listens on 0.0.0.0:4570, returns rid. */
|
|
||||||
function listen() {
|
|
||||||
return ops.op_listen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Accepts a connection, returns rid. */
|
|
||||||
function accept(serverRid) {
|
|
||||||
return opAsync("op_accept", serverRid);
|
|
||||||
}
|
|
||||||
|
|
||||||
function read(serverRid, buf) {
|
|
||||||
return opAsync2("op_read_socket", serverRid, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function serve(rid) {
|
async function serve(rid) {
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
await read(rid, requestBuf);
|
await op_read_socket(rid, requestBuf);
|
||||||
if (!ops.op_try_write(rid, responseBuf)) {
|
if (!ops.op_try_write(rid, responseBuf)) {
|
||||||
await Deno.core.writeAll(rid, responseBuf);
|
await Deno.core.writeAll(rid, responseBuf);
|
||||||
}
|
}
|
||||||
|
@ -41,11 +36,12 @@ async function serve(rid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const listenerRid = listen();
|
/** Listens on 0.0.0.0:4570, returns rid. */
|
||||||
|
const listenerRid = op_listen();
|
||||||
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4570/\n`);
|
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4570/\n`);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const rid = await accept(listenerRid);
|
const rid = await op_accept(listenerRid);
|
||||||
serve(rid);
|
serve(rid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2765,9 +2765,9 @@ pub mod tests {
|
||||||
.execute_script_static(
|
.execute_script_static(
|
||||||
"filename.js",
|
"filename.js",
|
||||||
r#"
|
r#"
|
||||||
|
const { op_test } = Deno.core.generateAsyncOpHandler("op_test");
|
||||||
let zero_copy_a = new Uint8Array([0]);
|
let zero_copy_a = new Uint8Array([0]);
|
||||||
Deno.core.opAsync2("op_test", null, zero_copy_a);
|
op_test(null, zero_copy_a);
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
const ops = core.ops;
|
const ops = core.ops;
|
||||||
|
const {
|
||||||
|
op_chmod_async,
|
||||||
|
op_ftruncate_async,
|
||||||
|
op_truncate_async,
|
||||||
|
op_link_async,
|
||||||
|
op_flock_async,
|
||||||
|
} = Deno.core.generateAsyncOpHandler(
|
||||||
|
"op_chmod_async",
|
||||||
|
"op_ftruncate_async",
|
||||||
|
"op_truncate_async",
|
||||||
|
"op_link_async",
|
||||||
|
"op_flock_async",
|
||||||
|
);
|
||||||
const primordials = globalThis.__bootstrap.primordials;
|
const primordials = globalThis.__bootstrap.primordials;
|
||||||
const {
|
const {
|
||||||
ArrayPrototypeFilter,
|
ArrayPrototypeFilter,
|
||||||
|
@ -34,7 +49,7 @@ function chmodSync(path, mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function chmod(path, mode) {
|
async function chmod(path, mode) {
|
||||||
await core.opAsync2("op_chmod_async", pathFromURL(path), mode);
|
await op_chmod_async(pathFromURL(path), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function chownSync(
|
function chownSync(
|
||||||
|
@ -347,7 +362,7 @@ function ftruncateSync(rid, len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ftruncate(rid, len) {
|
async function ftruncate(rid, len) {
|
||||||
await core.opAsync2("op_ftruncate_async", rid, coerceLen(len));
|
await op_ftruncate_async(rid, coerceLen(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
function truncateSync(path, len) {
|
function truncateSync(path, len) {
|
||||||
|
@ -355,7 +370,7 @@ function truncateSync(path, len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function truncate(path, len) {
|
async function truncate(path, len) {
|
||||||
await core.opAsync2("op_truncate_async", path, coerceLen(len));
|
await op_truncate_async(path, coerceLen(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
function umask(mask) {
|
function umask(mask) {
|
||||||
|
@ -367,7 +382,7 @@ function linkSync(oldpath, newpath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function link(oldpath, newpath) {
|
async function link(oldpath, newpath) {
|
||||||
await core.opAsync2("op_link_async", oldpath, newpath);
|
await op_link_async(oldpath, newpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toUnixTimeFromEpoch(value) {
|
function toUnixTimeFromEpoch(value) {
|
||||||
|
@ -497,7 +512,7 @@ function flockSync(rid, exclusive) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flock(rid, exclusive) {
|
async function flock(rid, exclusive) {
|
||||||
await core.opAsync2("op_flock_async", rid, exclusive === true);
|
await op_flock_async(rid, exclusive === true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function funlockSync(rid) {
|
function funlockSync(rid) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ const {
|
||||||
op_set_response_headers,
|
op_set_response_headers,
|
||||||
op_upgrade_raw,
|
op_upgrade_raw,
|
||||||
op_ws_server_create,
|
op_ws_server_create,
|
||||||
} = Deno.core.generateAsyncOpHandler(
|
} = core.generateAsyncOpHandler(
|
||||||
"op_http_wait",
|
"op_http_wait",
|
||||||
"op_upgrade",
|
"op_upgrade",
|
||||||
"op_get_request_headers",
|
"op_get_request_headers",
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
const internals = globalThis.__bootstrap.internals;
|
const internals = globalThis.__bootstrap.internals;
|
||||||
const primordials = globalThis.__bootstrap.primordials;
|
const primordials = globalThis.__bootstrap.primordials;
|
||||||
const { BadResourcePrototype, InterruptedPrototype, ops } = core;
|
const { BadResourcePrototype, InterruptedPrototype, ops } = core;
|
||||||
|
const { op_http_write } = Deno.core.generateAsyncOpHandler("op_http_write");
|
||||||
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
||||||
import { InnerBody } from "ext:deno_fetch/22_body.js";
|
import { InnerBody } from "ext:deno_fetch/22_body.js";
|
||||||
import { Event, setEventTargetData } from "ext:deno_web/02_event.js";
|
import { Event, setEventTargetData } from "ext:deno_web/02_event.js";
|
||||||
|
@ -321,7 +325,7 @@ function createRespondWith(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await core.opAsync2("op_http_write", streamRid, value);
|
await op_http_write(streamRid, value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const connError = httpConn[connErrorSymbol];
|
const connError = httpConn[connErrorSymbol];
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
|
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
|
|
||||||
import { notImplemented } from "ext:deno_node/_utils.ts";
|
import { notImplemented } from "ext:deno_node/_utils.ts";
|
||||||
import randomBytes from "ext:deno_node/internal/crypto/_randomBytes.ts";
|
import randomBytes from "ext:deno_node/internal/crypto/_randomBytes.ts";
|
||||||
import randomFill, {
|
import randomFill, {
|
||||||
|
@ -31,6 +33,15 @@ export { default as randomInt } from "ext:deno_node/internal/crypto/_randomInt.t
|
||||||
|
|
||||||
const { core } = globalThis.__bootstrap;
|
const { core } = globalThis.__bootstrap;
|
||||||
const { ops } = core;
|
const { ops } = core;
|
||||||
|
const {
|
||||||
|
op_node_gen_prime_async,
|
||||||
|
op_node_check_prime_bytes_async,
|
||||||
|
op_node_check_prime_async,
|
||||||
|
} = Deno.core.generateAsyncOpHandler(
|
||||||
|
"op_node_gen_prime_async",
|
||||||
|
"op_node_check_prime_bytes_async",
|
||||||
|
"op_node_check_prime_async",
|
||||||
|
);
|
||||||
|
|
||||||
export type LargeNumberLike =
|
export type LargeNumberLike =
|
||||||
| ArrayBufferView
|
| ArrayBufferView
|
||||||
|
@ -79,9 +90,9 @@ export function checkPrime(
|
||||||
|
|
||||||
validateInt32(checks, "options.checks", 0);
|
validateInt32(checks, "options.checks", 0);
|
||||||
|
|
||||||
let op = "op_node_check_prime_bytes_async";
|
let op = op_node_check_prime_bytes_async;
|
||||||
if (typeof candidate === "bigint") {
|
if (typeof candidate === "bigint") {
|
||||||
op = "op_node_check_prime_async";
|
op = op_node_check_prime_async;
|
||||||
} else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) {
|
} else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) {
|
||||||
throw new ERR_INVALID_ARG_TYPE(
|
throw new ERR_INVALID_ARG_TYPE(
|
||||||
"candidate",
|
"candidate",
|
||||||
|
@ -96,7 +107,7 @@ export function checkPrime(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
core.opAsync2(op, candidate, checks).then(
|
op(candidate, checks).then(
|
||||||
(result) => {
|
(result) => {
|
||||||
callback?.(null, result);
|
callback?.(null, result);
|
||||||
},
|
},
|
||||||
|
@ -160,7 +171,7 @@ export function generatePrime(
|
||||||
const {
|
const {
|
||||||
bigint,
|
bigint,
|
||||||
} = validateRandomPrimeJob(size, options);
|
} = validateRandomPrimeJob(size, options);
|
||||||
core.opAsync2("op_node_gen_prime_async", size).then((prime: Uint8Array) =>
|
op_node_gen_prime_async(size).then((prime: Uint8Array) =>
|
||||||
bigint ? arrayBufferToUnsignedBigInt(prime.buffer) : prime.buffer
|
bigint ? arrayBufferToUnsignedBigInt(prime.buffer) : prime.buffer
|
||||||
).then((prime: ArrayBuffer | bigint) => {
|
).then((prime: ArrayBuffer | bigint) => {
|
||||||
callback?.(null, prime);
|
callback?.(null, prime);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
const ops = core.ops;
|
const ops = core.ops;
|
||||||
const primordials = globalThis.__bootstrap.primordials;
|
const primordials = globalThis.__bootstrap.primordials;
|
||||||
|
@ -13,7 +15,6 @@ const {
|
||||||
MapPrototypeSet,
|
MapPrototypeSet,
|
||||||
Uint8Array,
|
Uint8Array,
|
||||||
Uint32Array,
|
Uint32Array,
|
||||||
// deno-lint-ignore camelcase
|
|
||||||
NumberPOSITIVE_INFINITY,
|
NumberPOSITIVE_INFINITY,
|
||||||
PromisePrototypeThen,
|
PromisePrototypeThen,
|
||||||
SafeArrayIterator,
|
SafeArrayIterator,
|
||||||
|
@ -26,6 +27,7 @@ const {
|
||||||
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
||||||
import { reportException } from "ext:deno_web/02_event.js";
|
import { reportException } from "ext:deno_web/02_event.js";
|
||||||
import { assert } from "ext:deno_web/00_infra.js";
|
import { assert } from "ext:deno_web/00_infra.js";
|
||||||
|
const { op_sleep } = core.generateAsyncOpHandler("op_sleep");
|
||||||
|
|
||||||
const hrU8 = new Uint8Array(8);
|
const hrU8 = new Uint8Array(8);
|
||||||
const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8));
|
const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8));
|
||||||
|
@ -216,7 +218,7 @@ const scheduledTimers = { head: null, tail: null };
|
||||||
*/
|
*/
|
||||||
function runAfterTimeout(cb, millis, timerInfo) {
|
function runAfterTimeout(cb, millis, timerInfo) {
|
||||||
const cancelRid = timerInfo.cancelRid;
|
const cancelRid = timerInfo.cancelRid;
|
||||||
const sleepPromise = core.opAsync2("op_sleep", millis, cancelRid);
|
const sleepPromise = op_sleep(millis, cancelRid);
|
||||||
timerInfo.promiseId = sleepPromise[SymbolFor("Deno.core.internalPromiseId")];
|
timerInfo.promiseId = sleepPromise[SymbolFor("Deno.core.internalPromiseId")];
|
||||||
if (!timerInfo.isRef) {
|
if (!timerInfo.isRef) {
|
||||||
core.unrefOp(timerInfo.promiseId);
|
core.unrefOp(timerInfo.promiseId);
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
/// <reference path="../../core/internal.d.ts" />
|
/// <reference path="../../core/internal.d.ts" />
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
const { opAsync, opAsync2 } = core;
|
|
||||||
// deno-lint-ignore camelcase
|
|
||||||
const op_ws_check_permission_and_cancel_handle =
|
|
||||||
core.ops.op_ws_check_permission_and_cancel_handle;
|
|
||||||
import { URL } from "ext:deno_url/00_url.js";
|
import { URL } from "ext:deno_url/00_url.js";
|
||||||
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
||||||
import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js";
|
import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js";
|
||||||
|
@ -51,6 +48,23 @@ const {
|
||||||
TypedArrayPrototypeGetByteLength,
|
TypedArrayPrototypeGetByteLength,
|
||||||
TypedArrayPrototypeGetSymbolToStringTag,
|
TypedArrayPrototypeGetSymbolToStringTag,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
const op_ws_check_permission_and_cancel_handle =
|
||||||
|
core.ops.op_ws_check_permission_and_cancel_handle;
|
||||||
|
const {
|
||||||
|
op_ws_create,
|
||||||
|
op_ws_close,
|
||||||
|
op_ws_send_binary,
|
||||||
|
op_ws_send_text,
|
||||||
|
op_ws_next_event,
|
||||||
|
op_ws_send_ping,
|
||||||
|
} = core.generateAsyncOpHandler(
|
||||||
|
"op_ws_create",
|
||||||
|
"op_ws_close",
|
||||||
|
"op_ws_send_binary",
|
||||||
|
"op_ws_send_text",
|
||||||
|
"op_ws_next_event",
|
||||||
|
"op_ws_send_ping",
|
||||||
|
);
|
||||||
|
|
||||||
webidl.converters["sequence<DOMString> or DOMString"] = (
|
webidl.converters["sequence<DOMString> or DOMString"] = (
|
||||||
V,
|
V,
|
||||||
|
@ -252,8 +266,7 @@ class WebSocket extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
opAsync(
|
op_ws_create(
|
||||||
"op_ws_create",
|
|
||||||
"new WebSocket()",
|
"new WebSocket()",
|
||||||
wsURL.href,
|
wsURL.href,
|
||||||
ArrayPrototypeJoin(protocols, ", "),
|
ArrayPrototypeJoin(protocols, ", "),
|
||||||
|
@ -265,7 +278,7 @@ class WebSocket extends EventTarget {
|
||||||
|
|
||||||
if (this[_readyState] === CLOSING) {
|
if (this[_readyState] === CLOSING) {
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
opAsync("op_ws_close", this[_rid]),
|
op_ws_close(this[_rid]),
|
||||||
() => {
|
() => {
|
||||||
this[_readyState] = CLOSED;
|
this[_readyState] = CLOSED;
|
||||||
|
|
||||||
|
@ -318,8 +331,7 @@ class WebSocket extends EventTarget {
|
||||||
const sendTypedArray = (view, byteLength) => {
|
const sendTypedArray = (view, byteLength) => {
|
||||||
this[_bufferedAmount] += byteLength;
|
this[_bufferedAmount] += byteLength;
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
opAsync2(
|
op_ws_send_binary(
|
||||||
"op_ws_send_binary",
|
|
||||||
this[_rid],
|
this[_rid],
|
||||||
view,
|
view,
|
||||||
),
|
),
|
||||||
|
@ -353,8 +365,7 @@ class WebSocket extends EventTarget {
|
||||||
const d = core.encode(string);
|
const d = core.encode(string);
|
||||||
this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d);
|
this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d);
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
opAsync2(
|
op_ws_send_text(
|
||||||
"op_ws_send_text",
|
|
||||||
this[_rid],
|
this[_rid],
|
||||||
string,
|
string,
|
||||||
),
|
),
|
||||||
|
@ -407,8 +418,7 @@ class WebSocket extends EventTarget {
|
||||||
this[_readyState] = CLOSING;
|
this[_readyState] = CLOSING;
|
||||||
|
|
||||||
PromisePrototypeCatch(
|
PromisePrototypeCatch(
|
||||||
opAsync(
|
op_ws_close(
|
||||||
"op_ws_close",
|
|
||||||
this[_rid],
|
this[_rid],
|
||||||
code,
|
code,
|
||||||
reason,
|
reason,
|
||||||
|
@ -432,10 +442,7 @@ class WebSocket extends EventTarget {
|
||||||
|
|
||||||
async [_eventLoop]() {
|
async [_eventLoop]() {
|
||||||
while (this[_readyState] !== CLOSED) {
|
while (this[_readyState] !== CLOSED) {
|
||||||
const { 0: kind, 1: value } = await opAsync2(
|
const { 0: kind, 1: value } = await op_ws_next_event(this[_rid]);
|
||||||
"op_ws_next_event",
|
|
||||||
this[_rid],
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case 0: {
|
case 0: {
|
||||||
|
@ -495,8 +502,7 @@ class WebSocket extends EventTarget {
|
||||||
|
|
||||||
if (prevState === OPEN) {
|
if (prevState === OPEN) {
|
||||||
try {
|
try {
|
||||||
await opAsync(
|
await op_ws_close(
|
||||||
"op_ws_close",
|
|
||||||
this[_rid],
|
this[_rid],
|
||||||
code,
|
code,
|
||||||
value,
|
value,
|
||||||
|
@ -524,17 +530,12 @@ class WebSocket extends EventTarget {
|
||||||
clearTimeout(this[_idleTimeoutTimeout]);
|
clearTimeout(this[_idleTimeoutTimeout]);
|
||||||
this[_idleTimeoutTimeout] = setTimeout(async () => {
|
this[_idleTimeoutTimeout] = setTimeout(async () => {
|
||||||
if (this[_readyState] === OPEN) {
|
if (this[_readyState] === OPEN) {
|
||||||
await opAsync("op_ws_send_ping", this[_rid]);
|
await op_ws_send_ping(this[_rid]);
|
||||||
this[_idleTimeoutTimeout] = setTimeout(async () => {
|
this[_idleTimeoutTimeout] = setTimeout(async () => {
|
||||||
if (this[_readyState] === OPEN) {
|
if (this[_readyState] === OPEN) {
|
||||||
this[_readyState] = CLOSING;
|
this[_readyState] = CLOSING;
|
||||||
const reason = "No response from ping frame.";
|
const reason = "No response from ping frame.";
|
||||||
await opAsync(
|
await op_ws_close(this[_rid], 1001, reason);
|
||||||
"op_ws_close",
|
|
||||||
this[_rid],
|
|
||||||
1001,
|
|
||||||
reason,
|
|
||||||
);
|
|
||||||
this[_readyState] = CLOSED;
|
this[_readyState] = CLOSED;
|
||||||
|
|
||||||
const errEvent = new ErrorEvent("error", {
|
const errEvent = new ErrorEvent("error", {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// deno-lint-ignore-file camelcase
|
||||||
/// <reference path="../../core/internal.d.ts" />
|
/// <reference path="../../core/internal.d.ts" />
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
|
@ -32,6 +33,19 @@ const {
|
||||||
TypedArrayPrototypeGetByteLength,
|
TypedArrayPrototypeGetByteLength,
|
||||||
Uint8ArrayPrototype,
|
Uint8ArrayPrototype,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
const {
|
||||||
|
op_ws_send_text,
|
||||||
|
op_ws_send_binary,
|
||||||
|
op_ws_next_event,
|
||||||
|
op_ws_create,
|
||||||
|
op_ws_close,
|
||||||
|
} = core.generateAsyncOpHandler(
|
||||||
|
"op_ws_send_text",
|
||||||
|
"op_ws_send_binary",
|
||||||
|
"op_ws_next_event",
|
||||||
|
"op_ws_create",
|
||||||
|
"op_ws_close",
|
||||||
|
);
|
||||||
|
|
||||||
webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter(
|
webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter(
|
||||||
"WebSocketStreamOptions",
|
"WebSocketStreamOptions",
|
||||||
|
@ -153,8 +167,7 @@ class WebSocketStream {
|
||||||
};
|
};
|
||||||
options.signal?.[add](abort);
|
options.signal?.[add](abort);
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
core.opAsync(
|
op_ws_create(
|
||||||
"op_ws_create",
|
|
||||||
"new WebSocketStream()",
|
"new WebSocketStream()",
|
||||||
this[_url],
|
this[_url],
|
||||||
options.protocols ? ArrayPrototypeJoin(options.protocols, ", ") : "",
|
options.protocols ? ArrayPrototypeJoin(options.protocols, ", ") : "",
|
||||||
|
@ -165,15 +178,12 @@ class WebSocketStream {
|
||||||
options.signal?.[remove](abort);
|
options.signal?.[remove](abort);
|
||||||
if (this[_earlyClose]) {
|
if (this[_earlyClose]) {
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
core.opAsync("op_ws_close", create.rid),
|
op_ws_close(create.rid),
|
||||||
() => {
|
() => {
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
(async () => {
|
(async () => {
|
||||||
while (true) {
|
while (true) {
|
||||||
const { 0: kind } = await core.opAsync(
|
const { 0: kind } = await op_ws_next_event(create.rid);
|
||||||
"op_ws_next_event",
|
|
||||||
create.rid,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (kind > 5) {
|
if (kind > 5) {
|
||||||
/* close */
|
/* close */
|
||||||
|
@ -206,11 +216,11 @@ class WebSocketStream {
|
||||||
const writable = new WritableStream({
|
const writable = new WritableStream({
|
||||||
write: async (chunk) => {
|
write: async (chunk) => {
|
||||||
if (typeof chunk === "string") {
|
if (typeof chunk === "string") {
|
||||||
await core.opAsync2("op_ws_send_text", this[_rid], chunk);
|
await op_ws_send_text(this[_rid], chunk);
|
||||||
} else if (
|
} else if (
|
||||||
ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk)
|
ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk)
|
||||||
) {
|
) {
|
||||||
await core.opAsync2("op_ws_send_binary", this[_rid], chunk);
|
await op_ws_send_binary(this[_rid], chunk);
|
||||||
} else {
|
} else {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
"A chunk may only be either a string or an Uint8Array",
|
"A chunk may only be either a string or an Uint8Array",
|
||||||
|
@ -235,10 +245,7 @@ class WebSocketStream {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const pull = async (controller) => {
|
const pull = async (controller) => {
|
||||||
const { 0: kind, 1: value } = await core.opAsync2(
|
const { 0: kind, 1: value } = await op_ws_next_event(this[_rid]);
|
||||||
"op_ws_next_event",
|
|
||||||
this[_rid],
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -402,7 +409,7 @@ class WebSocketStream {
|
||||||
this[_earlyClose] = true;
|
this[_earlyClose] = true;
|
||||||
} else if (this[_closed].state === "pending") {
|
} else if (this[_closed].state === "pending") {
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
core.opAsync("op_ws_close", this[_rid], code, closeInfo.reason),
|
op_ws_close(this[_rid], code, closeInfo.reason),
|
||||||
() => {
|
() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this[_closeSent].resolve(DateNow());
|
this[_closeSent].resolve(DateNow());
|
||||||
|
|
Loading…
Reference in a new issue