Hide todos in the legacy folder
This commit is contained in:
@@ -5,15 +5,18 @@ use std::marker::PhantomData;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{BitAnd, Deref};
|
use std::ops::{BitAnd, Deref};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use derive_destructure::destructure;
|
use derive_destructure::destructure;
|
||||||
use dyn_clone::{DynClone, clone_box};
|
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::future::LocalBoxFuture;
|
||||||
use futures::lock::Mutex;
|
use futures::lock::Mutex;
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{AsyncBufRead, AsyncWrite, SinkExt, Stream, StreamExt};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
|
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
|
||||||
use trait_set::trait_set;
|
use trait_set::trait_set;
|
||||||
@@ -23,6 +26,72 @@ use crate::logging::Logger;
|
|||||||
|
|
||||||
pub struct Receipt<'a>(PhantomData<&'a mut ()>);
|
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! {
|
trait_set! {
|
||||||
pub trait SendFn<T: MsgSet> =
|
pub trait SendFn<T: MsgSet> =
|
||||||
for<'a> FnMut(&'a [u8], ReqNot<T>) -> LocalBoxFuture<'a, ()>
|
for<'a> FnMut(&'a [u8], ReqNot<T>) -> LocalBoxFuture<'a, ()>
|
||||||
@@ -52,11 +121,10 @@ impl ReqHandlish for &'_ dyn ReqHandlish {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(destructure)]
|
#[derive(destructure)]
|
||||||
pub struct RequestHandle<'a, MS: MsgSet> {
|
pub struct RequestHandle<MS: MsgSet> {
|
||||||
defer_drop: RefCell<Vec<Box<dyn Any>>>,
|
defer_drop: RefCell<Vec<Box<dyn Any>>>,
|
||||||
fulfilled: AtomicBool,
|
fulfilled: AtomicBool,
|
||||||
id: u64,
|
id: u64,
|
||||||
_reqlt: PhantomData<&'a mut ()>,
|
|
||||||
parent: ReqNot<MS>,
|
parent: ReqNot<MS>,
|
||||||
}
|
}
|
||||||
impl<'a, MS: MsgSet + 'static> RequestHandle<'a, 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> {
|
impl<MS: MsgSet> ReqHandlish for RequestHandle<'_, MS> {
|
||||||
fn defer_drop_objsafe(&self, val: Box<dyn Any>) { self.defer_drop.borrow_mut().push(val); }
|
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) {
|
fn drop(&mut self) {
|
||||||
let done = self.fulfilled.load(Ordering::Relaxed);
|
let done = self.fulfilled.load(Ordering::Relaxed);
|
||||||
debug_assert!(done, "Request {} dropped without response", self.id)
|
debug_assert!(done, "Request {} dropped without response", self.id)
|
||||||
@@ -123,7 +191,7 @@ impl<T: MsgSet> ReqNot<T> {
|
|||||||
notif: impl NotifFn<T>,
|
notif: impl NotifFn<T>,
|
||||||
req: impl ReqFn<T>,
|
req: impl ReqFn<T>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self(
|
let this = Self(
|
||||||
Arc::new(Mutex::new(ReqNotData {
|
Arc::new(Mutex::new(ReqNotData {
|
||||||
id: 1,
|
id: 1,
|
||||||
send: Box::new(send),
|
send: Box::new(send),
|
||||||
@@ -132,7 +200,13 @@ impl<T: MsgSet> ReqNot<T> {
|
|||||||
responses: HashMap::new(),
|
responses: HashMap::new(),
|
||||||
})),
|
})),
|
||||||
logger,
|
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
|
/// Can be called from a polling thread or dispatched in any other way
|
||||||
|
|||||||
@@ -55,6 +55,10 @@
|
|||||||
],
|
],
|
||||||
"rust-analyzer.showUnlinkedFileNotification": false,
|
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||||
"swissknife.notesEnabled": false,
|
"swissknife.notesEnabled": false,
|
||||||
|
"todo-tree.filtering.excludeGlobs": [
|
||||||
|
"**/node_modules/*/**",
|
||||||
|
"orchidlang/**"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
|
|||||||
Reference in New Issue
Block a user