sfo_cmd_server/client/
mod.rs

1mod client;
2
3use std::hash::Hash;
4use std::ops::Deref;
5use std::sync::Arc;
6use std::time::Duration;
7use bucky_raw_codec::{RawDecode, RawEncode, RawFixedBytes};
8use callback_result::CallbackWaiter;
9use num::{FromPrimitive, ToPrimitive};
10use sfo_pool::WorkerClassification;
11pub use client::*;
12
13mod classified_client;
14pub use classified_client::*;
15
16use crate::{CmdBody, CmdHandler, CmdTunnelMeta, PeerId, TunnelId};
17use crate::errors::CmdResult;
18
19pub trait CmdSend<M: CmdTunnelMeta>: Send + 'static {
20    fn get_tunnel_meta(&self) -> Option<Arc<M>>;
21    fn get_remote_peer_id(&self) -> PeerId;
22}
23
24pub trait SendGuard<M: CmdTunnelMeta, S: CmdSend<M>>: Send + 'static + Deref<Target = S>  {
25}
26
27#[async_trait::async_trait]
28pub trait CmdClient<LEN: RawEncode + for<'a> RawDecode<'a> + Copy + RawFixedBytes + Sync + Send + 'static + FromPrimitive + ToPrimitive,
29    CMD: RawEncode + for<'a> RawDecode<'a> + Copy + RawFixedBytes + Sync + Send + 'static + Eq + Hash,
30    M: CmdTunnelMeta,
31    S: CmdSend<M>,
32    G: SendGuard<M, S>>: Send + Sync + 'static {
33    fn register_cmd_handler(&self, cmd: CMD, handler: impl CmdHandler<LEN, CMD>);
34    async fn send(&self, cmd: CMD, version: u8, body: &[u8]) -> CmdResult<()>;
35    async fn send_with_resp(&self, cmd: CMD, version: u8, body: &[u8], timeout: Duration) -> CmdResult<CmdBody>;
36    async fn send2(&self, cmd: CMD, version: u8, body: &[&[u8]]) -> CmdResult<()>;
37    async fn send2_with_resp(&self, cmd: CMD, version: u8, body: &[&[u8]], timeout: Duration) -> CmdResult<CmdBody>;
38    async fn send_cmd(&self, cmd: CMD, version: u8, body: CmdBody) -> CmdResult<()>;
39    async fn send_cmd_with_resp(&self, cmd: CMD, version: u8, body: CmdBody, timeout: Duration) -> CmdResult<CmdBody>;
40    async fn send_by_specify_tunnel(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: &[u8]) -> CmdResult<()>;
41    async fn send_by_specify_tunnel_with_resp(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: &[u8], timeout: Duration) -> CmdResult<CmdBody>;
42    async fn send2_by_specify_tunnel(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: &[&[u8]]) -> CmdResult<()>;
43    async fn send2_by_specify_tunnel_with_resp(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: &[&[u8]], timeout: Duration) -> CmdResult<CmdBody>;
44    async fn send_cmd_by_specify_tunnel(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: CmdBody) -> CmdResult<()>;
45    async fn send_cmd_by_specify_tunnel_with_resp(&self, tunnel_id: TunnelId, cmd: CMD, version: u8, body: CmdBody, timeout: Duration) -> CmdResult<CmdBody>;
46    async fn clear_all_tunnel(&self);
47    async fn get_send(&self, tunnel_id: TunnelId) -> CmdResult<G>;
48}
49
50#[async_trait::async_trait]
51pub trait ClassifiedCmdClient<LEN: RawEncode + for<'a> RawDecode<'a> + Copy + RawFixedBytes + Sync + Send + 'static + FromPrimitive + ToPrimitive,
52    CMD: RawEncode + for<'a> RawDecode<'a> + Copy + RawFixedBytes + Sync + Send + 'static + Eq + Hash,
53    C: WorkerClassification,
54    M: CmdTunnelMeta,
55    S: CmdSend<M>,
56    G: SendGuard<M, S>>: CmdClient<LEN, CMD, M, S, G> {
57    async fn send_by_classified_tunnel(&self, classification: C, cmd: CMD, version: u8, body: &[u8]) -> CmdResult<()>;
58    async fn send_by_classified_tunnel_with_resp(&self, classification: C, cmd: CMD, version: u8, body: &[u8], timeout: Duration) -> CmdResult<CmdBody>;
59    async fn send2_by_classified_tunnel(&self, classification: C, cmd: CMD, version: u8, body: &[&[u8]]) -> CmdResult<()>;
60    async fn send2_by_classified_tunnel_with_resp(&self, classification: C, cmd: CMD, version: u8, body: &[&[u8]], timeout: Duration) -> CmdResult<CmdBody>;
61    async fn send_cmd_by_classified_tunnel(&self, classification: C, cmd: CMD, version: u8, body: CmdBody) -> CmdResult<()>;
62    async fn send_cmd_by_classified_tunnel_with_resp(&self, classification: C, cmd: CMD, version: u8, body: CmdBody, timeout: Duration) -> CmdResult<CmdBody>;
63    async fn find_tunnel_id_by_classified(&self, classification: C) -> CmdResult<TunnelId>;
64    async fn get_send_by_classified(&self, classification: C) -> CmdResult<G>;
65}
66
67
68pub(crate) type RespWaiter = CallbackWaiter<u64, CmdBody>;
69pub(crate) type RespWaiterRef = Arc<RespWaiter>;
70
71pub(crate) fn gen_resp_id<CMD: RawEncode + for<'a> RawDecode<'a> + Copy + RawFixedBytes + Sync + Send + 'static>(cmd: CMD, seq: u32) -> u64 {
72    let cmd_buf = cmd.raw_encode_to_buffer().unwrap();
73    let mut id = seq as u64;
74    let cmd = if cmd_buf.len() > 4 {
75        u32::from_be_bytes(cmd_buf[..4].try_into().unwrap())
76    } else {
77        let mut buf = [0u8; 4];
78        buf[..cmd_buf.len()].copy_from_slice(&cmd_buf);
79        u32::from_be_bytes(buf)
80    };
81    id |= (cmd as u64) << 32;
82    id
83}
84
85pub(crate) fn gen_seq() -> u32 {
86    rand::random::<u32>()
87}