//! HTTP requests share the harness inbox. Replies never leave the V8 thread as JS values. use deno_core::{OpState, op2}; use serde_json::Value; use std::{cell::RefCell, collections::HashMap, rc::Rc}; use tokio::sync::mpsc::UnboundedSender; pub(super) struct Reply { pub sender: UnboundedSender, pub finished: std::sync::Arc, } pub(super) type Replies = HashMap; #[op2] pub fn op_harness_reply( state: &mut OpState, #[string] id: String, #[serde] value: serde_json::Value, ) { let replies = state.borrow_mut::(); if value.is_null() { if let Some(reply) = replies.remove(&id) { reply.finished.notify_one(); } } else if let Some(reply) = replies.get(&id) { let _ = reply.sender.send(value); } } #[op2] pub async fn op_harness_closed(state: Rc>, #[string] id: String) { let reply = state .borrow() .borrow::() .get(&id) .map(|reply| (reply.sender.clone(), reply.finished.clone())); if let Some((sender, finished)) = reply { tokio::select! { _ = sender.closed() => {}, _ = finished.notified() => {}, } } state.borrow_mut().borrow_mut::().remove(&id); }