43 lines
1.3 KiB
Rust
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);
|
|
}
|