Hide todos in the legacy folder
This commit is contained in:
@@ -5,15 +5,18 @@ use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::{BitAnd, Deref};
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
use derive_destructure::destructure;
|
||||
use dyn_clone::{DynClone, clone_box};
|
||||
use futures::channel::mpsc;
|
||||
use futures::channel::mpsc::{self, Sender};
|
||||
use futures::channel::oneshot;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::lock::Mutex;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use futures::{AsyncBufRead, AsyncWrite, SinkExt, Stream, StreamExt};
|
||||
use hashbrown::HashMap;
|
||||
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
|
||||
use trait_set::trait_set;
|
||||
@@ -23,6 +26,72 @@ use crate::logging::Logger;
|
||||
|
||||
pub struct Receipt<'a>(PhantomData<&'a mut ()>);
|
||||
|
||||
/// This object holds an exclusive lock on the outbound pipe.
|
||||
pub trait DynRequestWriter {
|
||||
fn writer(&mut self) -> Pin<&mut dyn AsyncWrite>;
|
||||
/// Release the outbound pipe and wait for the response to begin.
|
||||
fn get_response(self: Box<Self>) -> Pin<Box<dyn Future<Output = Box<dyn DynResponseHandle>>>>;
|
||||
}
|
||||
/// This object holds an exclusive lock on the inbound pipe.
|
||||
pub trait DynResponseHandle {
|
||||
fn reader(&mut self) -> Pin<&mut dyn AsyncBufRead>;
|
||||
fn finish(self: Box<Self>) -> Pin<Box<dyn Future<Output = ()>>>;
|
||||
}
|
||||
/// This object holds an exclusive lock on the outbound pipe.
|
||||
pub trait DynNotifWriter {
|
||||
fn writer(&mut self) -> Pin<&mut dyn AsyncWrite>;
|
||||
fn finish(self: Box<Self>) -> Pin<Box<dyn Future<Output = ()>>>;
|
||||
}
|
||||
|
||||
pub trait DynClient {
|
||||
fn request(&self) -> Pin<Box<dyn Future<Output = Box<dyn DynRequestWriter>>>>;
|
||||
fn notif(&self) -> Pin<Box<dyn Future<Output = Box<dyn DynNotifWriter>>>>;
|
||||
}
|
||||
|
||||
pub struct Client<T: MsgSet>(pub(crate) Rc<dyn DynClient>, pub(crate) PhantomData<T>);
|
||||
impl<T: MsgSet> Client<T> {
|
||||
pub async fn notify<Notif: Into<<T::Out as Channel>::Notif>>(&self, notif: Notif) {
|
||||
let mut notif_writer = self.0.notif().await;
|
||||
notif.into().encode(notif_writer.writer()).await;
|
||||
notif_writer.finish().await;
|
||||
}
|
||||
pub async fn request<Req: Request + Into<<T::Out as Channel>::Req>>(
|
||||
&self,
|
||||
req: Req,
|
||||
) -> Req::Response {
|
||||
let root_req = req.into();
|
||||
let mut req_writer = self.0.request().await;
|
||||
root_req.encode(req_writer.writer()).await;
|
||||
let mut req_hand = req_writer.get_response().await;
|
||||
let res = Req::Response::decode(req_hand.reader()).await;
|
||||
req_hand.finish().await;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DuplexServerState {
|
||||
pending_outbound: HashMap<u64, Box<dyn FnOnce(&mut dyn AsyncBufRead)>>,
|
||||
sender: Pin<Box<dyn AsyncWrite>>,
|
||||
receiver: Pin<Box<dyn AsyncBufRead>>,
|
||||
}
|
||||
pub enum ServerEvent<T: MsgSet> {
|
||||
Notif(<T::In as Channel>::Notif),
|
||||
Req(RequestHandle<T>, <T::In as Channel>::Req),
|
||||
}
|
||||
pub async fn run_duplex_server<T: MsgSet>(
|
||||
sender: Pin<Box<dyn AsyncWrite>>,
|
||||
receiver: Pin<Box<dyn AsyncBufRead>>,
|
||||
) -> (impl Stream<Item = ServerEvent<T>>, Client<T>) {
|
||||
let sender = Rc::new(Mutex::new(sender));
|
||||
let receiver = Rc::new(Mutex::new(receiver));
|
||||
let pending_outbound = Rc::new(Mutex::new(HashMap::new()));
|
||||
|
||||
}
|
||||
pub struct DuplexServer(Rc<Mutex<DuplexServerState>>);
|
||||
impl DuplexServer {
|
||||
pub fn receive(msg: )
|
||||
}
|
||||
|
||||
trait_set! {
|
||||
pub trait SendFn<T: MsgSet> =
|
||||
for<'a> FnMut(&'a [u8], ReqNot<T>) -> LocalBoxFuture<'a, ()>
|
||||
@@ -52,11 +121,10 @@ impl ReqHandlish for &'_ dyn ReqHandlish {
|
||||
}
|
||||
|
||||
#[derive(destructure)]
|
||||
pub struct RequestHandle<'a, MS: MsgSet> {
|
||||
pub struct RequestHandle<MS: MsgSet> {
|
||||
defer_drop: RefCell<Vec<Box<dyn Any>>>,
|
||||
fulfilled: AtomicBool,
|
||||
id: u64,
|
||||
_reqlt: PhantomData<&'a mut ()>,
|
||||
parent: ReqNot<MS>,
|
||||
}
|
||||
impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> {
|
||||
@@ -89,7 +157,7 @@ impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> {
|
||||
impl<MS: MsgSet> ReqHandlish for RequestHandle<'_, MS> {
|
||||
fn defer_drop_objsafe(&self, val: Box<dyn Any>) { self.defer_drop.borrow_mut().push(val); }
|
||||
}
|
||||
impl<MS: MsgSet> Drop for RequestHandle<'_, MS> {
|
||||
impl<MS: MsgSet> Drop for RequestHandle<MS> {
|
||||
fn drop(&mut self) {
|
||||
let done = self.fulfilled.load(Ordering::Relaxed);
|
||||
debug_assert!(done, "Request {} dropped without response", self.id)
|
||||
@@ -123,7 +191,7 @@ impl<T: MsgSet> ReqNot<T> {
|
||||
notif: impl NotifFn<T>,
|
||||
req: impl ReqFn<T>,
|
||||
) -> Self {
|
||||
Self(
|
||||
let this = Self(
|
||||
Arc::new(Mutex::new(ReqNotData {
|
||||
id: 1,
|
||||
send: Box::new(send),
|
||||
@@ -132,7 +200,13 @@ impl<T: MsgSet> ReqNot<T> {
|
||||
responses: HashMap::new(),
|
||||
})),
|
||||
logger,
|
||||
)
|
||||
);
|
||||
let (sig_send, sig_recv) = std::sync::mpsc::sync_channel(0);
|
||||
std::thread::spawn(move || {
|
||||
std::thread::sleep(Duration::from_secs(10));
|
||||
sig_send.send(()).expect("Crash!");
|
||||
});
|
||||
this
|
||||
}
|
||||
|
||||
/// Can be called from a polling thread or dispatched in any other way
|
||||
|
||||
Reference in New Issue
Block a user