2022-02-21 11:04:09 +00:00
|
|
|
use std::borrow::Borrow;
|
2021-10-12 15:59:46 +00:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use arc_swap::ArcSwapOption;
|
|
|
|
use async_trait::async_trait;
|
|
|
|
|
2022-06-07 22:30:56 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2021-10-12 15:59:46 +00:00
|
|
|
|
|
|
|
use crate::error::Error;
|
|
|
|
use crate::netapp::*;
|
|
|
|
use crate::proto::*;
|
|
|
|
use crate::util::*;
|
|
|
|
|
|
|
|
/// This trait should be implemented by all messages your application
|
2021-10-14 09:35:05 +00:00
|
|
|
/// wants to handle
|
2022-06-05 13:33:43 +00:00
|
|
|
pub trait Message: SerializeMessage + Send + Sync {
|
|
|
|
type Response: SerializeMessage + Send + Sync;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A trait for de/serializing messages, with possible associated stream.
|
|
|
|
#[async_trait]
|
|
|
|
pub trait SerializeMessage: Sized {
|
2022-06-07 22:30:56 +00:00
|
|
|
type SerializableSelf: Serialize + for<'de> Deserialize<'de> + Send;
|
2022-06-05 13:33:43 +00:00
|
|
|
|
2022-06-07 22:30:56 +00:00
|
|
|
fn serialize_msg(&self) -> (Self::SerializableSelf, Option<AssociatedStream>);
|
|
|
|
|
|
|
|
// TODO should return Result
|
|
|
|
async fn deserialize_msg(ser_self: Self::SerializableSelf, stream: AssociatedStream) -> Self;
|
2022-06-05 13:33:43 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 22:30:56 +00:00
|
|
|
pub trait AutoSerialize: Serialize + for<'de> Deserialize<'de> + Clone + Send + Sync {}
|
|
|
|
|
2022-06-05 13:33:43 +00:00
|
|
|
#[async_trait]
|
|
|
|
impl<T> SerializeMessage for T
|
|
|
|
where
|
2022-06-07 22:30:56 +00:00
|
|
|
T: AutoSerialize,
|
2022-06-05 13:33:43 +00:00
|
|
|
{
|
2022-06-07 22:30:56 +00:00
|
|
|
type SerializableSelf = Self;
|
|
|
|
fn serialize_msg(&self) -> (Self::SerializableSelf, Option<AssociatedStream>) {
|
|
|
|
(self.clone(), None)
|
|
|
|
}
|
|
|
|
|
2022-06-19 15:44:07 +00:00
|
|
|
async fn deserialize_msg(ser_self: Self::SerializableSelf, _stream: AssociatedStream) -> Self {
|
2022-06-07 22:30:56 +00:00
|
|
|
// TODO verify no stream
|
|
|
|
ser_self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AutoSerialize for () {}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl<T, E> SerializeMessage for Result<T, E>
|
|
|
|
where
|
|
|
|
T: SerializeMessage + Send,
|
|
|
|
E: SerializeMessage + Send,
|
|
|
|
{
|
|
|
|
type SerializableSelf = Result<T::SerializableSelf, E::SerializableSelf>;
|
|
|
|
|
|
|
|
fn serialize_msg(&self) -> (Self::SerializableSelf, Option<AssociatedStream>) {
|
|
|
|
match self {
|
|
|
|
Ok(ok) => {
|
|
|
|
let (msg, stream) = ok.serialize_msg();
|
|
|
|
(Ok(msg), stream)
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
let (msg, stream) = err.serialize_msg();
|
|
|
|
(Err(msg), stream)
|
|
|
|
}
|
|
|
|
}
|
2022-06-05 13:33:43 +00:00
|
|
|
}
|
|
|
|
|
2022-06-07 22:30:56 +00:00
|
|
|
async fn deserialize_msg(ser_self: Self::SerializableSelf, stream: AssociatedStream) -> Self {
|
|
|
|
match ser_self {
|
|
|
|
Ok(ok) => Ok(T::deserialize_msg(ok, stream).await),
|
|
|
|
Err(err) => Err(E::deserialize_msg(err, stream).await),
|
2022-06-05 13:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-12 15:59:46 +00:00
|
|
|
}
|
|
|
|
|
2021-10-14 09:35:05 +00:00
|
|
|
/// This trait should be implemented by an object of your application
|
|
|
|
/// that can handle a message of type `M`.
|
|
|
|
///
|
|
|
|
/// The handler object should be in an Arc, see `Endpoint::set_handler`
|
2021-10-12 15:59:46 +00:00
|
|
|
#[async_trait]
|
|
|
|
pub trait EndpointHandler<M>: Send + Sync
|
|
|
|
where
|
|
|
|
M: Message,
|
|
|
|
{
|
2021-10-14 12:54:48 +00:00
|
|
|
async fn handle(self: &Arc<Self>, m: &M, from: NodeID) -> M::Response;
|
2021-10-12 15:59:46 +00:00
|
|
|
}
|
|
|
|
|
2021-10-14 09:35:05 +00:00
|
|
|
/// If one simply wants to use an endpoint in a client fashion,
|
|
|
|
/// without locally serving requests to that endpoint,
|
|
|
|
/// use the unit type `()` as the handler type:
|
|
|
|
/// it will panic if it is ever made to handle request.
|
|
|
|
#[async_trait]
|
|
|
|
impl<M: Message + 'static> EndpointHandler<M> for () {
|
2021-10-14 12:54:48 +00:00
|
|
|
async fn handle(self: &Arc<()>, _m: &M, _from: NodeID) -> M::Response {
|
2021-10-14 09:35:05 +00:00
|
|
|
panic!("This endpoint should not have a local handler.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This struct represents an endpoint for message of type `M`.
|
|
|
|
///
|
|
|
|
/// Creating a new endpoint is done by calling `NetApp::endpoint`.
|
|
|
|
/// An endpoint is identified primarily by its path, which is specified
|
|
|
|
/// at creation time.
|
|
|
|
///
|
|
|
|
/// An `Endpoint` is used both to send requests to remote nodes,
|
|
|
|
/// and to specify the handler for such requests on the local node.
|
|
|
|
/// The type `H` represents the type of the handler object for
|
|
|
|
/// endpoint messages (see `EndpointHandler`).
|
2021-10-12 15:59:46 +00:00
|
|
|
pub struct Endpoint<M, H>
|
|
|
|
where
|
|
|
|
M: Message,
|
|
|
|
H: EndpointHandler<M>,
|
|
|
|
{
|
|
|
|
phantom: PhantomData<M>,
|
|
|
|
netapp: Arc<NetApp>,
|
|
|
|
path: String,
|
|
|
|
handler: ArcSwapOption<H>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<M, H> Endpoint<M, H>
|
|
|
|
where
|
|
|
|
M: Message,
|
|
|
|
H: EndpointHandler<M>,
|
|
|
|
{
|
|
|
|
pub(crate) fn new(netapp: Arc<NetApp>, path: String) -> Self {
|
|
|
|
Self {
|
|
|
|
phantom: PhantomData::default(),
|
|
|
|
netapp,
|
|
|
|
path,
|
|
|
|
handler: ArcSwapOption::from(None),
|
|
|
|
}
|
|
|
|
}
|
2021-10-14 09:35:05 +00:00
|
|
|
|
2022-02-16 12:00:26 +00:00
|
|
|
/// Get the path of this endpoint
|
|
|
|
pub fn path(&self) -> &str {
|
|
|
|
&self.path
|
|
|
|
}
|
|
|
|
|
2021-10-14 09:35:05 +00:00
|
|
|
/// Set the object that is responsible of handling requests to
|
|
|
|
/// this endpoint on the local node.
|
2021-10-12 15:59:46 +00:00
|
|
|
pub fn set_handler(&self, h: Arc<H>) {
|
|
|
|
self.handler.swap(Some(h));
|
|
|
|
}
|
2021-10-14 09:35:05 +00:00
|
|
|
|
|
|
|
/// Call this endpoint on a remote node (or on the local node,
|
|
|
|
/// for that matter)
|
2022-02-21 11:01:04 +00:00
|
|
|
pub async fn call<B>(
|
2021-10-12 15:59:46 +00:00
|
|
|
&self,
|
|
|
|
target: &NodeID,
|
2022-02-21 11:01:04 +00:00
|
|
|
req: B,
|
2021-10-12 15:59:46 +00:00
|
|
|
prio: RequestPriority,
|
2022-02-21 11:04:09 +00:00
|
|
|
) -> Result<<M as Message>::Response, Error>
|
|
|
|
where
|
2022-06-07 22:30:56 +00:00
|
|
|
B: Borrow<M> + Send + Sync,
|
2022-02-21 11:04:09 +00:00
|
|
|
{
|
2021-10-12 15:59:46 +00:00
|
|
|
if *target == self.netapp.id {
|
|
|
|
match self.handler.load_full() {
|
|
|
|
None => Err(Error::NoHandler),
|
2022-02-21 11:01:04 +00:00
|
|
|
Some(h) => Ok(h.handle(req.borrow(), self.netapp.id).await),
|
2021-10-12 15:59:46 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let conn = self
|
|
|
|
.netapp
|
|
|
|
.client_conns
|
|
|
|
.read()
|
|
|
|
.unwrap()
|
|
|
|
.get(target)
|
|
|
|
.cloned();
|
|
|
|
match conn {
|
|
|
|
None => Err(Error::Message(format!(
|
|
|
|
"Not connected: {}",
|
2022-02-21 15:57:07 +00:00
|
|
|
hex::encode(&target[..8])
|
2021-10-12 15:59:46 +00:00
|
|
|
))),
|
|
|
|
Some(c) => c.call(req, self.path.as_str(), prio).await,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-14 09:35:05 +00:00
|
|
|
// ---- Internal stuff ----
|
|
|
|
|
|
|
|
pub(crate) type DynEndpoint = Box<dyn GenericEndpoint + Send + Sync>;
|
|
|
|
|
2021-10-12 15:59:46 +00:00
|
|
|
#[async_trait]
|
|
|
|
pub(crate) trait GenericEndpoint {
|
2022-06-05 13:33:43 +00:00
|
|
|
async fn handle(
|
|
|
|
&self,
|
|
|
|
buf: &[u8],
|
|
|
|
stream: AssociatedStream,
|
|
|
|
from: NodeID,
|
|
|
|
) -> Result<(Vec<u8>, Option<AssociatedStream>), Error>;
|
2021-10-14 15:33:12 +00:00
|
|
|
fn drop_handler(&self);
|
2021-10-12 15:59:46 +00:00
|
|
|
fn clone_endpoint(&self) -> DynEndpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub(crate) struct EndpointArc<M, H>(pub(crate) Arc<Endpoint<M, H>>)
|
|
|
|
where
|
|
|
|
M: Message,
|
|
|
|
H: EndpointHandler<M>;
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl<M, H> GenericEndpoint for EndpointArc<M, H>
|
|
|
|
where
|
|
|
|
M: Message + 'static,
|
|
|
|
H: EndpointHandler<M> + 'static,
|
|
|
|
{
|
2022-06-05 13:33:43 +00:00
|
|
|
async fn handle(
|
|
|
|
&self,
|
|
|
|
buf: &[u8],
|
|
|
|
stream: AssociatedStream,
|
|
|
|
from: NodeID,
|
|
|
|
) -> Result<(Vec<u8>, Option<AssociatedStream>), Error> {
|
2021-10-12 15:59:46 +00:00
|
|
|
match self.0.handler.load_full() {
|
|
|
|
None => Err(Error::NoHandler),
|
|
|
|
Some(h) => {
|
2022-06-07 22:30:56 +00:00
|
|
|
let req = rmp_serde::decode::from_read_ref(buf)?;
|
|
|
|
let req = M::deserialize_msg(req, stream).await;
|
2021-10-14 12:54:48 +00:00
|
|
|
let res = h.handle(&req, from).await;
|
2021-10-12 15:59:46 +00:00
|
|
|
let res_bytes = rmp_to_vec_all_named(&res)?;
|
|
|
|
Ok(res_bytes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-14 15:33:12 +00:00
|
|
|
fn drop_handler(&self) {
|
2021-10-12 15:59:46 +00:00
|
|
|
self.0.handler.swap(None);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn clone_endpoint(&self) -> DynEndpoint {
|
|
|
|
Box::new(Self(self.0.clone()))
|
|
|
|
}
|
|
|
|
}
|