diff --git a/README.md b/README.md index 8aaca0e..ee472d5 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ with param_scope(**{"foo.x": 2}): fn foo() -> i32 { with_params! { get x = foo.x or 1i32; // Read hyperparameter with default value + println!("x={}", x); } } @@ -70,6 +71,7 @@ fn main() { with_params! { set foo.x = 2i32; // Set hyperparameter + foo(); // x=2 } @@ -129,6 +131,7 @@ with_params!{ // 1st scope start with_params!{ //2nd scope start set foo.y=2 + ... } // 2nd scope end } // 1st scope end ``` diff --git a/README.zh.md b/README.zh.md index a9543c2..811fb4a 100644 --- a/README.zh.md +++ b/README.zh.md @@ -61,6 +61,7 @@ with param_scope(**{"foo.x": 2}): fn foo() -> i32 { with_params! { get x = foo.x or 1i32; // 读取带有默认值的超参数 + println!("x={}", x); } } @@ -70,6 +71,7 @@ fn main() { with_params! { set foo.x = 2i32; // 设置超参数 + foo(); // x=2 } @@ -129,6 +131,7 @@ with_params!{ // 第1个作用域开始 with_params!{ //第2个作用域开始 set foo.y=2 + ... } // 第2个作用域结束 } // 第1个作用域结束 ``` diff --git a/examples/debug_server.rs b/examples/debug_server.rs deleted file mode 100644 index 4652122..0000000 --- a/examples/debug_server.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::io::Error; -use std::process::exit; -use std::thread::sleep; -use std::time::Duration; - -use signal_hook; - -use hyperparameter::debug::start_debug_server; -use hyperparameter::debug::REPL; - -struct DebugRepl { - buf: String, - live: bool, -} - -impl DebugRepl { - pub fn new() -> DebugRepl { - DebugRepl { - buf: "".to_string(), - live: true, - } - } - fn process(&mut self, cmd: &String) -> Option { - if cmd.trim() == "exit".to_string() { - self.live = false - } - return Some(cmd.clone()); - } -} - -impl REPL for DebugRepl { - fn feed(&mut self, s: String) -> Option { - self.buf += &s; - if !self.buf.contains("\n") { - return None; - } - let cmd = match self.buf.split_once("\n") { - Some((cmd, rest)) => { - let cmd = cmd.to_string(); - self.buf = rest.to_string(); - Some(cmd) - } - None => None, - }; - if let Some(cmd) = cmd { - self.process(&cmd) - } else { - None - } - } - - fn is_alive(&self) -> bool { - self.live - } -} - -fn debug_callback() { - let mut repl = DebugRepl::new(); - start_debug_server(Some("127.0.0.1:9900".to_string()), &mut repl); - exit(0) -} - -pub fn main() -> Result<(), Error> { - unsafe { - signal_hook::low_level::register(signal_hook::consts::SIGUSR1, move || debug_callback())?; - signal_hook::low_level::register(signal_hook::consts::SIGABRT, move || debug_callback())?; - } - - for i in 0..1000 { - sleep(Duration::from_secs(1)); - println!("{}", i); - } - - Ok(()) -} diff --git a/hyperparameter/src/debug.rs b/hyperparameter/src/debug.rs deleted file mode 100644 index c522a9c..0000000 --- a/hyperparameter/src/debug.rs +++ /dev/null @@ -1,154 +0,0 @@ -use std::{io::Error, thread, time::Duration}; - -use ::backtrace::Backtrace; -use hyperparameter::debug::{start_async_server, start_debug_server, REPL}; -use pyo3::{prelude::*, types::PyDict}; - -struct DebugRepl { - console: Option>, - buf: String, - live: bool, -} - -impl Default for DebugRepl { - fn default() -> Self { - Self { - console: Some(create_console()), - buf: "".to_string(), - live: true, - } - } -} - -impl DebugRepl { - pub fn new(console: Option>) -> DebugRepl { - DebugRepl { - console, - buf: "".to_string(), - live: true, - } - } - fn process(&mut self, cmd: &str) -> Option { - if cmd.trim() == "exit".to_string() { - self.live = false - } - let ret = self.console.as_ref().map(|console| { - Python::with_gil(|py| { - let args = (cmd.to_string().into_py(py),); - let ret = console.call_method(py, "push", args, None); - match ret { - Ok(obj) => { - if obj.is_none(py) { - None - } else { - Some(obj.to_string()) - } - } - Err(err) => Some(err.to_string()), - } - }) - }); - if let Some(ret) = ret { - ret - } else { - None - } - } -} - -impl REPL for DebugRepl { - fn feed(&mut self, s: String) -> Option { - self.buf += &s; - if !self.buf.contains("\n") { - return None; - } - let cmd = match self.buf.split_once("\n") { - Some((cmd, rest)) => { - let cmd = cmd.to_string(); - self.buf = rest.to_string(); - Some(cmd) - } - None => None, - }; - if let Some(cmd) = cmd { - self.process(&cmd) - } else { - None - } - } - - fn is_alive(&self) -> bool { - self.live - } -} - -fn create_console() -> Py { - Python::with_gil(|py| { - let locals = PyDict::new(py); - let ret = Python::run( - py, - r#" -import hyperparameter -ret = hyperparameter.DebugConsole() -ret.init() - "#, - None, - Some(locals), - ); - if ret.is_err() { - ret.map_err(|err| { - err.print(py); - }) - .unwrap(); - py.None(); - } - let ret = match locals.get_item("ret").unwrap() { - Some(x) => x.to_object(py), - None => py.None(), - }; - ret - }) -} - -pub fn debug_callback(addr: Option) { - let console = create_console(); - let mut repl = DebugRepl::new(Some(console)); - start_debug_server(addr, &mut repl); -} - -#[pyfunction] -#[pyo3(signature = (addr=None, background=false))] -pub fn enable_debug_server(addr: Option, background: bool) -> Result<(), Error> { - unsafe { - let tmp = addr.clone(); - signal_hook::low_level::register(signal_hook::consts::SIGUSR1, move || { - debug_callback(tmp.clone()) - })?; - let tmp = addr.clone(); - signal_hook::low_level::register(signal_hook::consts::SIGABRT, move || { - debug_callback(tmp.clone()) - })?; - } - if background { - thread::spawn(|| { - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(start_async_server::(addr)) - .unwrap(); - }); - } - Ok(()) -} - -#[pyfunction] -pub fn sleep(secs: u64) { - std::thread::sleep(Duration::from_secs(secs)) -} - -#[pyfunction] -pub fn backtrace() -> String { - let bt = Backtrace::new(); - format!("{:?}", bt) -} diff --git a/hyperparameter/src/ext.rs b/hyperparameter/src/ext.rs index 14cfbd4..b180b69 100644 --- a/hyperparameter/src/ext.rs +++ b/hyperparameter/src/ext.rs @@ -13,9 +13,6 @@ use pyo3::types::PyList; use pyo3::types::PyString; use pyo3::FromPyPointer; -use crate::debug::enable_debug_server; -use crate::debug::sleep; - #[repr(C)] enum UserDefinedType { PyObjectType = 1, @@ -198,8 +195,5 @@ pub fn xxh64(s: &str) -> u64 { fn librbackend(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_function(wrap_pyfunction!(xxh64, m)?)?; - m.add_function(wrap_pyfunction!(sleep, m)?)?; - m.add_function(wrap_pyfunction!(enable_debug_server, m)?)?; - m.add_function(wrap_pyfunction!(crate::debug::backtrace, m)?)?; Ok(()) } diff --git a/hyperparameter/src/lib.rs b/hyperparameter/src/lib.rs index 2d1a7d5..310a957 100644 --- a/hyperparameter/src/lib.rs +++ b/hyperparameter/src/lib.rs @@ -1,2 +1 @@ -pub mod debug; pub mod ext; diff --git a/src/debug/async_server.rs b/src/debug/async_server.rs deleted file mode 100644 index d6af2e3..0000000 --- a/src/debug/async_server.rs +++ /dev/null @@ -1,132 +0,0 @@ -use nu_ansi_term::Color; -use std::{error::Error, marker::PhantomData}; -use tokio::{ - io::{AsyncReadExt, AsyncWriteExt}, - net::TcpListener, -}; - -use crate::debug::debug_server::REPL; -use local_ip_address::list_afinet_netifas; -use local_ip_address::local_ip; -pub struct AsyncServer { - self_addr: Option, - prompt: Option, - phantom: PhantomData, -} - -unsafe impl Send for AsyncServer {} - -impl Default for AsyncServer { - fn default() -> Self { - Self { - self_addr: Some("0.0.0.0:0".to_string()), - prompt: None, - phantom: PhantomData, - } - } -} - -impl AsyncServer { - pub fn new(addr: String) -> Self { - Self { - self_addr: Some(addr), - prompt: None, - phantom: PhantomData, - } - } - - pub async fn run(&mut self) -> Result<(), Box> { - let listener = TcpListener::bind(self.self_addr.as_ref().unwrap()).await?; - self.self_addr = match listener.local_addr() { - Ok(addr) => { - if addr.to_string().contains("0.0.0.0:") { - println!( - "{} {}, available addresses:", - Color::Red.bold().paint("Debug Server is started on"), - Color::Green.bold().underline().paint(addr.to_string()) - ); - for (name, ip) in list_afinet_netifas().unwrap().iter() { - if !ip.is_ipv4() { - continue; - } - let if_addr = ip.to_string(); - println!( - "\t{}: {}", - Color::Yellow.paint(name), - Color::Blue - .bold() - .underline() - .paint(addr.to_string().replace("0.0.0.0", &if_addr)) - ); - } - - let local_addr = local_ip().unwrap().to_string(); - Some(addr.to_string().replace("0.0.0.0", &local_addr)) - } else { - println!( - "{} {}", - Color::Red.bold().paint("Debug Server is started on"), - Color::Green.bold().underline().paint(addr.to_string()) - ); - Some(addr.to_string()) - } - } - Err(err) => { - println!("error binding debug server address: {}", err.to_string()); - None - } - }; - self.prompt = self.self_addr.as_ref().map(|addr| format!("({})>>", addr)); - - self.serve(&listener).await - } - - async fn serve(&self, listener: &TcpListener) -> Result<(), Box> { - loop { - let (mut stream, addr) = listener.accept().await?; - let prompt = self.get_prompt().to_string(); - // Spawn our handler to be run asynchronously. - tokio::spawn(async move { - println!( - "{} {}", - Color::Yellow.italic().paint("debug server connection from"), - Color::Green.italic().underline().paint(addr.to_string()) - ); - let mut repl = Box::new(T::default()); - let mut buf = [0; 1024]; - let _ = stream.write(prompt.as_bytes()).await; - loop { - let n = match stream.read(&mut buf).await { - Ok(n) if n == 0 => break, - Ok(n) => n, - Err(_) => break, - }; - let req = String::from_utf8(buf[0..n].to_vec()); - let s = match repl.feed(req.clone().unwrap()) { - Some(rsp) => format!("{}\n{}", rsp, prompt), - None => prompt.to_string(), - }; - if stream.write(s.as_bytes()).await.is_err() { - break; - } - } - }); - } - } - - fn get_prompt(&self) -> &str { - self.prompt.as_ref().map_or(">>", |s| s.as_str()) - } -} - -pub async fn start_async_server(addr: Option) -> Result<(), Box> -where - T: REPL + Default + Send, -{ - let mut server = match addr { - Some(addr) => AsyncServer::::new(addr), - None => AsyncServer::::default(), - }; - server.run().await?; - Ok(()) -} diff --git a/src/debug/debug_server.rs b/src/debug/debug_server.rs deleted file mode 100644 index c84ed29..0000000 --- a/src/debug/debug_server.rs +++ /dev/null @@ -1,96 +0,0 @@ -use std::io::Read; -use std::io::Write; - -use std::net::TcpListener; -use std::net::TcpStream; - -pub trait REPL { - fn feed(&mut self, s: String) -> Option; - fn is_alive(&self) -> bool; -} - -pub struct DebugServer { - self_addr: Option, - peer_addr: Option, - prompt: Option, -} - -impl Default for DebugServer { - fn default() -> Self { - Self { - self_addr: Some("127.0.0.1:0".to_string()), - peer_addr: None, - prompt: Default::default(), - } - } -} - -impl DebugServer { - pub fn new(addr: String) -> Self { - Self { - self_addr: Some(addr), - peer_addr: None, - prompt: Default::default(), - } - } - - pub fn run(&mut self, repl: &mut dyn REPL) { - let listener = TcpListener::bind(self.self_addr.as_ref().unwrap()).unwrap(); - self.self_addr = match listener.local_addr() { - Ok(addr) => { - println!("debug server is started on {}", addr); - Some(addr.to_string()) - } - Err(_) => None, - }; - self.prompt = self.self_addr.as_ref().map(|addr| format!("({})>>", addr)); - - for stream in listener.incoming() { - let exit = stream.map_or(true, |mut s| self.handle(&mut s, repl)); - if exit { - break; - }; - } - } - - fn show_prompt(&self, stream: &mut TcpStream) { - let _ = stream.write(self.get_prompt().as_bytes()); - } - - fn get_prompt(&self) -> &str { - self.prompt.as_ref().map_or(">>", |s| s.as_str()) - } - - fn handle(&mut self, stream: &mut TcpStream, repl: &mut dyn REPL) -> bool { - self.peer_addr = stream.peer_addr().map(|addr| addr.to_string()).ok(); - if let Some(addr) = &self.peer_addr { - println!("debug server connection from {}", addr); - } - self.show_prompt(stream); - let mut buf = [0; 1024]; - loop { - let n = match stream.read(&mut buf) { - Ok(n) if n == 0 => return true, - Ok(n) => n, - Err(_) => break, - }; - let req = String::from_utf8(buf[0..n].to_vec()); - let s = match repl.feed(req.unwrap()) { - Some(rsp) => format!("{}\n{}", rsp, self.get_prompt()), - None => self.get_prompt().to_string(), - }; - if stream.write(s.as_bytes()).is_err() | !repl.is_alive() { - break; - } - } - !repl.is_alive() - } -} - -pub fn start_debug_server(addr: Option, repl: &mut dyn REPL) { - let mut server = match addr { - Some(addr) => DebugServer::new(addr), - None => DebugServer::default(), - }; - server.run(repl); -} diff --git a/src/debug/mod.rs b/src/debug/mod.rs deleted file mode 100644 index d6971dd..0000000 --- a/src/debug/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod async_server; -pub mod debug_server; - -pub use crate::debug::async_server::start_async_server; -pub use crate::debug::debug_server::start_debug_server; -pub use crate::debug::debug_server::REPL; diff --git a/src/lib.rs b/src/lib.rs index fda37e8..1f6b84a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,5 @@ pub mod value; pub mod api; pub mod cfg; -pub mod debug; pub mod ffi; pub mod xxh;