Files
sausage/host/src/harness/http.rs
T

43 lines
1.3 KiB
Rust

//! 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<Value>,
pub finished: std::sync::Arc<tokio::sync::Notify>,
}
pub(super) type Replies = HashMap<String, Reply>;
#[op2]
pub fn op_harness_reply(
state: &mut OpState,
#[string] id: String,
#[serde] value: serde_json::Value,
) {
let replies = state.borrow_mut::<Replies>();
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<RefCell<OpState>>, #[string] id: String) {
let reply = state
.borrow()
.borrow::<Replies>()
.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::<Replies>().remove(&id);
}