Skip to content

Commit

Permalink
refactor: rewrite websocket to use op2 macro (denoland#20140)
Browse files Browse the repository at this point in the history
Co-authored-by: Bartek Iwańczuk <[email protected]>
  • Loading branch information
littledivy and bartlomieju committed Oct 4, 2023
1 parent cbddf57 commit 1a81b28
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 43 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ repository = "https://github.com/denoland/deno"
[workspace.dependencies]
deno_ast = { version = "0.29.3", features = ["transpiling"] }

deno_core = { version = "0.220.0" }
deno_core = { version = "0.221.0" }

deno_runtime = { version = "0.128.0", path = "./runtime" }
napi_sym = { version = "0.50.0", path = "./cli/napi/sym" }
Expand Down
1 change: 1 addition & 0 deletions cli/js/40_testing.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ const OP_DETAILS = {
"op_ws_next_event": ["receive the next message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
"op_ws_send_text": ["send a message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
"op_ws_send_binary": ["send a message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
"op_ws_send_binary_ab": ["send a message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
"op_ws_send_ping": ["send a message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
"op_ws_send_pong": ["send a message on a WebSocket", "closing a `WebSocket` or `WebSocketStream`"],
};
Expand Down
8 changes: 2 additions & 6 deletions ext/websocket/01_websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const {
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypeSome,
DataView,
ErrorPrototypeToString,
ObjectDefineProperties,
ObjectPrototypeIsPrototypeOf,
Expand All @@ -50,6 +49,7 @@ const {
op_ws_create,
op_ws_close,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_text,
op_ws_next_event,
op_ws_get_buffer,
Expand Down Expand Up @@ -336,11 +336,7 @@ class WebSocket extends EventTarget {
PromisePrototypeThen(
// deno-lint-ignore prefer-primordials
data.slice().arrayBuffer(),
(ab) =>
op_ws_send_binary(
this[_rid],
new DataView(ab),
),
(ab) => op_ws_send_binary_ab(this[_rid], ab),
);
} else {
const string = String(data);
Expand Down
93 changes: 64 additions & 29 deletions ext/websocket/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use deno_core::error::invalid_hostname;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op;
use deno_core::op2;
use deno_core::url;
use deno_core::AsyncMutFuture;
use deno_core::AsyncRefCell;
Expand Down Expand Up @@ -108,11 +109,12 @@ impl Resource for WsCancelResource {
// This op is needed because creating a WS instance in JavaScript is a sync
// operation and should throw error when permissions are not fulfilled,
// but actual op that connects WS is async.
#[op]
#[op2]
#[smi]
pub fn op_ws_check_permission_and_cancel_handle<WP>(
state: &mut OpState,
api_name: String,
url: String,
#[string] api_name: String,
#[string] url: String,
cancel_handle: bool,
) -> Result<Option<ResourceId>, AnyError>
where
Expand Down Expand Up @@ -167,14 +169,15 @@ async fn handshake<S: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
Ok((stream, response))
}

#[op]
#[op2(async)]
#[serde]
pub async fn op_ws_create<WP>(
state: Rc<RefCell<OpState>>,
api_name: String,
url: String,
protocols: String,
cancel_handle: Option<ResourceId>,
headers: Option<Vec<(ByteString, ByteString)>>,
#[string] api_name: String,
#[string] url: String,
#[string] protocols: String,
#[smi] cancel_handle: Option<ResourceId>,
#[serde] headers: Option<Vec<(ByteString, ByteString)>>,
) -> Result<CreateResponse, AnyError>
where
WP: WebSocketPermissions + 'static,
Expand Down Expand Up @@ -407,8 +410,7 @@ pub fn ws_create_server_stream(
Ok(rid)
}

#[op(fast)]
pub fn op_ws_send_binary(state: &mut OpState, rid: ResourceId, data: &[u8]) {
fn send_binary(state: &mut OpState, rid: ResourceId, data: &[u8]) {
let resource = state.resource_table.get::<ServerWebSocket>(rid).unwrap();
let data = data.to_vec();
let len = data.len();
Expand All @@ -426,8 +428,30 @@ pub fn op_ws_send_binary(state: &mut OpState, rid: ResourceId, data: &[u8]) {
});
}

#[op(fast)]
pub fn op_ws_send_text(state: &mut OpState, rid: ResourceId, data: String) {
#[op2(fast)]
pub fn op_ws_send_binary(
state: &mut OpState,
#[smi] rid: ResourceId,
#[anybuffer] data: &[u8],
) {
send_binary(state, rid, data)
}

#[op2(fast)]
pub fn op_ws_send_binary_ab(
state: &mut OpState,
#[smi] rid: ResourceId,
#[arraybuffer] data: &[u8],
) {
send_binary(state, rid, data)
}

#[op2(fast)]
pub fn op_ws_send_text(
state: &mut OpState,
#[smi] rid: ResourceId,
#[string] data: String,
) {
let resource = state.resource_table.get::<ServerWebSocket>(rid).unwrap();
let len = data.len();
resource.buffered.set(resource.buffered.get() + len);
Expand Down Expand Up @@ -487,8 +511,12 @@ pub async fn op_ws_send_text_async(

const EMPTY_PAYLOAD: &[u8] = &[];

#[op(fast)]
pub fn op_ws_get_buffered_amount(state: &mut OpState, rid: ResourceId) -> u32 {
#[op2(fast)]
#[smi]
pub fn op_ws_get_buffered_amount(
state: &mut OpState,
#[smi] rid: ResourceId,
) -> u32 {
state
.resource_table
.get::<ServerWebSocket>(rid)
Expand All @@ -497,10 +525,10 @@ pub fn op_ws_get_buffered_amount(state: &mut OpState, rid: ResourceId) -> u32 {
.get() as u32
}

#[op]
#[op2(async)]
pub async fn op_ws_send_pong(
state: Rc<RefCell<OpState>>,
rid: ResourceId,
#[smi] rid: ResourceId,
) -> Result<(), AnyError> {
let resource = state
.borrow_mut()
Expand All @@ -512,10 +540,10 @@ pub async fn op_ws_send_pong(
.await
}

#[op]
#[op2(async)]
pub async fn op_ws_send_ping(
state: Rc<RefCell<OpState>>,
rid: ResourceId,
#[smi] rid: ResourceId,
) -> Result<(), AnyError> {
let resource = state
.borrow_mut()
Expand All @@ -530,12 +558,12 @@ pub async fn op_ws_send_ping(
.await
}

#[op(deferred)]
#[op2(async(lazy))]
pub async fn op_ws_close(
state: Rc<RefCell<OpState>>,
rid: ResourceId,
code: Option<u16>,
reason: Option<String>,
#[smi] rid: ResourceId,
#[smi] code: Option<u16>,
#[string] reason: Option<String>,
) -> Result<(), AnyError> {
let resource = state
.borrow_mut()
Expand All @@ -551,23 +579,29 @@ pub async fn op_ws_close(
Ok(())
}

#[op]
pub fn op_ws_get_buffer(state: &mut OpState, rid: ResourceId) -> ToJsBuffer {
#[op2]
#[serde]
pub fn op_ws_get_buffer(
state: &mut OpState,
#[smi] rid: ResourceId,
) -> ToJsBuffer {
let resource = state.resource_table.get::<ServerWebSocket>(rid).unwrap();
resource.buffer.take().unwrap().into()
}

#[op]
#[op2]
#[string]
pub fn op_ws_get_buffer_as_string(
state: &mut OpState,
rid: ResourceId,
#[smi] rid: ResourceId,
) -> String {
let resource = state.resource_table.get::<ServerWebSocket>(rid).unwrap();
resource.string.take().unwrap()
}

#[op]
pub fn op_ws_get_error(state: &mut OpState, rid: ResourceId) -> String {
#[op2]
#[string]
pub fn op_ws_get_error(state: &mut OpState, #[smi] rid: ResourceId) -> String {
let Ok(resource) = state.resource_table.get::<ServerWebSocket>(rid) else {
return "Bad resource".into();
};
Expand Down Expand Up @@ -660,6 +694,7 @@ deno_core::extension!(deno_websocket,
op_ws_get_buffer_as_string,
op_ws_get_error,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_text,
op_ws_send_binary_async,
op_ws_send_text_async,
Expand Down
2 changes: 1 addition & 1 deletion runtime/ops/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn op_main_module(state: &mut OpState) -> Result<String, AnyError> {

/// This is an op instead of being done at initialization time because
/// it's expensive to retrieve the ppid on Windows.
#[op2]
#[op2(fast)]
#[bigint]
pub fn op_ppid() -> i64 {
#[cfg(windows)]
Expand Down

0 comments on commit 1a81b28

Please sign in to comment.