lwleen-rpc 1.3.3

RPC (信令路由), 组件间数据通信
Documentation
//! ✅公用的类型
//! 
//! - TOOL工具  TIME时间
//! - 线程同步控制
//! 

// #![allow(unused_variables)]
#![allow(dead_code)]

use serde::{ Serialize, Deserialize };
use anyhow::{ Error as anyhow_Error, Result as anyhow_Result, anyhow as anyhow_err, Ok as anyhow_Ok };
use once_cell::sync::{OnceCell, Lazy};  
use std::sync::{ Arc, atomic::{ AtomicBool,AtomicUsize,AtomicU64,Ordering}};
use parking_lot::{ Mutex, RwLock, Condvar, Once}; 
use chrono::{self,TimeZone,Local};
use thiserror;




//--------- OnceCell初始化放在程序中,  Lazy紧跟初始化 ---------
pub static 全局_CPU数量: Lazy<usize> = Lazy::new(||{
    num_cpus::get() 
    // cfg_if!{
    //     if #[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]{  4   }
    //     else{ num_cpus::get() }
    // }
});        //延迟初始化
pub static 全局_启动时间: Lazy<u128> = Lazy::new(|| TIME时间::now_毫秒() );





pub struct TOOL工具;
impl TOOL工具 {
    /// - uuid v7
    pub fn uuid随机()-> uuid::Uuid { uuid::Uuid::now_v7()  }
}




pub struct TIME时间;
impl TIME时间 {
    /// - 毫秒 ms
    pub fn now_毫秒() ->  u128{        // !!!!🍁 wasm 不能出现  UNIX_EPOCH 否则报错 🍁!!!
        // std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis()
        chrono::Local::now().timestamp_millis() as u128  // 毫秒  0.001 s
    }
    pub fn now_纳秒() ->  u128{
        // std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos()
        chrono::Local::now().timestamp_nanos_opt().unwrap_or_default() as u128  // 毫秒  0.001 s
    }
    pub fn time_日期() -> String {
        chrono::Local::now().format("%Y/%m/%d %H:%M:%S").to_string()  // _%3f  显示毫秒
    }
    pub fn time_毫秒转日期(毫秒ms: u128 ) -> anyhow_Result<String> {
        let ms时间 = chrono::DateTime::from_timestamp_millis(毫秒ms as i64).ok_or(anyhow_err!("时间错误"))?; 
        let 时间 = ms时间.with_timezone(&chrono::Local);
        Ok(时间.format("%Y/%m/%d %H:%M:%S").to_string())
    }
    pub fn time_毫秒转24小时(毫秒ms: u128) -> String {
        let duration = chrono::Duration::milliseconds(毫秒ms as i64);
        format!("{:02}:{:02}:{:02}", duration.num_hours(), duration.num_minutes() % 60, duration.num_seconds() % 60 )
    }

    pub fn time_纳秒转时间字符串(纳秒 :u128, 纳秒级别:bool)->String{
      let mut num = 纳秒;
      let mut 字符串 = if 纳秒级别 { format!("{:>3}纳秒",num%1000) }else{ "".to_string() };  
      num = num / 1000;
      if num>0 { 字符串 = format!("{:>3}微秒{}{字符串}",num%1000, if 纳秒级别{"_"}else{""} );  num = num / 1000;  }
      if num>0 { 字符串 = format!("{:>3}毫秒_{字符串}", num%1000); num = num / 1000; }
      if num>0 { 字符串 = format!("{:>3}秒_{字符串}",num%1000);  }
      字符串
  }
}





//-------------- 原子ID
pub type 原子ID = u64;
#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)]
pub struct 原子ID对象(pub u64);
impl 原子ID对象 {
    pub fn next() -> Self {
        static 原子_ID_COUNTER: 原子inner = 原子inner::new();
        Self(原子_ID_COUNTER.next())
    }
}
pub struct 原子inner(AtomicU64);
impl 原子inner {
    pub const fn new() -> 原子inner { 原子inner(AtomicU64::new(1)) }
    pub fn next(&self) -> u64 { self.0.fetch_add(1, Ordering::Relaxed)    }    // Ordering::Relaxed    最弱,仅保证原子性,不保证内存顺序
    pub fn read(&self) -> u64 { self.0.load(Ordering::Relaxed)                 }
}
impl Default for 原子inner {  fn default() -> Self { Self::new() }   }










//-------------- 线程同步控制
struct 控制内部{
  pub 多线程共享变量:  Mutex<String>,
  pub 同步信号:  Condvar
}
#[derive(Clone)]
pub struct 线程同步控制{
    arc数据:  Arc<控制内部>,
}
impl 线程同步控制 {
    pub fn new(多线程变量:impl Into<String>)->Self{
        Self{
          arc数据: Arc::new(控制内部{
            多线程共享变量:Mutex::new(多线程变量.into()), 
            同步信号:Condvar::new(),
          })
        }
    }
    pub fn ref_Condvar(&self)->&Condvar{ &self.arc数据.同步信号 }
    pub fn 设置多线程共享变量(&self,变量值:impl Into<String>){  *self.arc数据.多线程共享变量.lock() = 变量值.into(); }
    pub fn 读取多线程共享变量(&self)->String{  self.arc数据.多线程共享变量.lock().clone()  }
    pub fn 广播多线程信号(&self,变量值:impl Into<String>){     *self.arc数据.多线程共享变量.lock() = 变量值.into();  self.arc数据.同步信号.notify_one();   }     //通知  阻塞的线程数据发送变化
    pub fn 广播多线程信号_全部(&self,变量值:impl Into<String>){ *self.arc数据.多线程共享变量.lock() = 变量值.into();  self.arc数据.同步信号.notify_all();   }     //通知  阻塞的线程数据发送变化
    
    /// 当共享变量为  `阻塞值`时  会阻塞线程
    pub fn 阻塞线程_尝试(&self, 阻塞值:impl AsRef<str>){
        let mut 共享变量 = self.arc数据.多线程共享变量.lock();   //获取锁
        // while *共享变量 == 阻塞值.as_ref() { self.arc数据.同步信号.wait(&mut 共享变量);  };
        self.arc数据.同步信号.wait_while(&mut 共享变量,|多线程变量|{ 多线程变量 == 阻塞值.as_ref() }  );
    }
    pub fn 阻塞线程_判断阻塞<F>(&self,mut 判断是否阻塞:F)
        where F:FnMut(&mut String)->bool 
    {
        let mut 共享变量 = self.arc数据.多线程共享变量.lock();     //获取锁
        self.arc数据.同步信号.wait_while(&mut 共享变量,|多线程变量: &mut String|{ 判断是否阻塞(多线程变量) }  ); 
    }
    /// 当共享变量为  `阻塞值`时  会阻塞线程
    pub fn 阻塞线程_循环回调<F>(&self, 阻塞值:impl AsRef<str>, 等待时间:std::time::Duration, mut 循环回调:F)
        where F: FnMut(&mut String),
    {
        let mut 共享变量 = self.arc数据.多线程共享变量.lock();   //获取锁
        while *共享变量 == 阻塞值.as_ref() {
            self.arc数据.同步信号.wait_for(&mut 共享变量, 等待时间 );
            循环回调(&mut 共享变量);
        }
    }
}

 
 





/// ### lwleen_rpc 信令路由 错误类型
#[derive(thiserror::Error, Debug)]
pub enum RpcError{
    // #[error("I/O 错误: {0}")]
    // err_IO错误(#[from] std::io::Error),                              //  自动实现  From trait,用于错误转换(如 io::Error → MyError  )
    // #[error("解析错误: 无法解析整数")]
    // err_数字解析(#[from] std::num::ParseIntError),                    //  定义错误的显示格式,支持格式化字符串
    // #[error("网络错误: {host} 连接超时 (端口 {port})")]
    // err_连接超时 { host: String, port: u16, },                        //  支持命名字段

    #[error("🍎🍎🍎【信令路由_执行函数错误】 err:{0}")]      //  支持元组
    err_rpc执行错误(#[from] anyhow::Error),
    #[error("🍎🍎🍎【信令路由_异步环境catch_unwind错误】{0}")]
    err_rpc执行错误_unwind(anyhow::Error),

    #[error("❌❌❌【信令路由_run同步完成】{0}")]
    err_run同步错误(anyhow::Error),
    #[error("❌❌❌【信令路由_await异步错误】{0}")]
    err_await异步错误(anyhow::Error),


    #[error("🧊🧊🧊【信令路由_线程池错】{0}")]
    err_rpc线程池错误(anyhow::Error),

    #[error("🍁🍁🍁【信令路由_通用错误】{0}")]
    err_rpc通用错误(#[from] Box<dyn std::error::Error + 'static>),

    
    #[error("未知错误")]
    err_未知,
}