api and log refactor

This commit is contained in:
John Smith
2022-07-01 12:13:52 -04:00
parent f409c84778
commit c106d324c8
25 changed files with 662 additions and 501 deletions

View File

@@ -3,6 +3,7 @@ use crate::tools::*;
use crate::veilid_client_capnp::*;
use capnp::capability::Promise;
use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, Disconnector, RpcSystem};
use serde::de::DeserializeOwned;
use std::cell::RefCell;
use std::net::SocketAddr;
use std::rc::Rc;
@@ -28,6 +29,30 @@ macro_rules! pry_result {
};
}
fn map_to_internal_error<T: ToString>(e: T) -> VeilidAPIError {
VeilidAPIError::Internal {
message: e.to_string(),
}
}
fn decode_api_result<T: DeserializeOwned + fmt::Debug>(
reader: &api_result::Reader,
) -> Result<T, VeilidAPIError> {
match reader.which().map_err(map_to_internal_error)? {
api_result::Which::Ok(v) => {
let ok_val = v.map_err(map_to_internal_error)?;
let res: T = veilid_core::deserialize_json(ok_val).map_err(map_to_internal_error)?;
Ok(res)
}
api_result::Which::Err(e) => {
let err_val = e.map_err(map_to_internal_error)?;
let res: VeilidAPIError =
veilid_core::deserialize_json(err_val).map_err(map_to_internal_error)?;
Err(res)
}
}
}
struct VeilidClientImpl {
comproc: CommandProcessor,
}
@@ -254,7 +279,13 @@ impl ClientApiConnection {
};
let request = server.borrow().attach_request();
let response = request.send().promise.await.map_err(map_to_string)?;
response.get().map(drop).map_err(map_to_string)
let reader = response
.get()
.map_err(map_to_string)?
.get_result()
.map_err(map_to_string)?;
let res: Result<(), VeilidAPIError> = decode_api_result(&reader);
res.map_err(map_to_string)
}
pub async fn server_detach(&mut self) -> Result<(), String> {
@@ -269,7 +300,13 @@ impl ClientApiConnection {
};
let request = server.borrow().detach_request();
let response = request.send().promise.await.map_err(map_to_string)?;
response.get().map(drop).map_err(map_to_string)
let reader = response
.get()
.map_err(map_to_string)?
.get_result()
.map_err(map_to_string)?;
let res: Result<(), VeilidAPIError> = decode_api_result(&reader);
res.map_err(map_to_string)
}
pub async fn server_shutdown(&mut self) -> Result<(), String> {
@@ -294,18 +331,47 @@ impl ClientApiConnection {
inner
.server
.as_ref()
.ok_or_else(|| "Not connected, ignoring attach request".to_owned())?
.ok_or_else(|| "Not connected, ignoring debug request".to_owned())?
.clone()
};
let mut request = server.borrow().debug_request();
request.get().set_what(&what);
request.get().set_command(&what);
let response = request.send().promise.await.map_err(map_to_string)?;
response
let reader = response
.get()
.map_err(map_to_string)?
.get_output()
.map(|o| o.to_owned())
.map_err(map_to_string)
.get_result()
.map_err(map_to_string)?;
let res: Result<String, VeilidAPIError> = decode_api_result(&reader);
res.map_err(map_to_string)
}
pub async fn server_change_log_level(
&mut self,
layer: String,
log_level: VeilidConfigLogLevel,
) -> Result<(), String> {
trace!("ClientApiConnection::change_log_level");
let server = {
let inner = self.inner.borrow();
inner
.server
.as_ref()
.ok_or_else(|| "Not connected, ignoring change_log_level request".to_owned())?
.clone()
};
let mut request = server.borrow().change_log_level_request();
request.get().set_layer(&layer);
let log_level_json = veilid_core::serialize_json(&log_level);
request.get().set_log_level(&log_level_json);
let response = request.send().promise.await.map_err(map_to_string)?;
let reader = response
.get()
.map_err(map_to_string)?
.get_result()
.map_err(map_to_string)?;
let res: Result<(), VeilidAPIError> = decode_api_result(&reader);
res.map_err(map_to_string)
}
// Start Client API connection

View File

@@ -8,6 +8,19 @@ use std::net::SocketAddr;
use std::rc::Rc;
use std::time::{Duration, SystemTime};
use veilid_core::xx::{Eventual, EventualCommon};
use veilid_core::VeilidConfigLogLevel;
pub fn convert_loglevel(s: &str) -> Result<VeilidConfigLogLevel, String> {
match s.to_ascii_lowercase().as_str() {
"off" => Ok(VeilidConfigLogLevel::Off),
"error" => Ok(VeilidConfigLogLevel::Error),
"warn" => Ok(VeilidConfigLogLevel::Warn),
"info" => Ok(VeilidConfigLogLevel::Info),
"debug" => Ok(VeilidConfigLogLevel::Debug),
"trace" => Ok(VeilidConfigLogLevel::Trace),
_ => Err(format!("Invalid log level: {}", s)),
}
}
#[derive(PartialEq, Clone)]
pub enum ConnectionState {
@@ -97,6 +110,7 @@ shutdown - shut the server down
attach - attach the server to the Veilid network
detach - detach the server from the Veilid network
debug - send a debugging command to the Veilid server
change_log_level - change the log level for a tracing layer
"#,
);
let ui = self.ui();
@@ -131,7 +145,7 @@ debug - send a debugging command to the Veilid server
let ui = self.ui();
spawn_detached_local(async move {
if let Err(e) = capi.server_attach().await {
error!("Server command 'attach' failed to execute: {}", e);
error!("Server command 'attach' failed: {}", e);
}
ui.send_callback(callback);
});
@@ -144,7 +158,7 @@ debug - send a debugging command to the Veilid server
let ui = self.ui();
spawn_detached_local(async move {
if let Err(e) = capi.server_detach().await {
error!("Server command 'detach' failed to execute: {}", e);
error!("Server command 'detach' failed: {}", e);
}
ui.send_callback(callback);
});
@@ -170,7 +184,40 @@ debug - send a debugging command to the Veilid server
match capi.server_debug(rest.unwrap_or_default()).await {
Ok(output) => ui.display_string_dialog("Debug Output", output, callback),
Err(e) => {
error!("Server command 'debug' failed to execute: {}", e);
error!("Server command 'debug' failed: {}", e);
ui.send_callback(callback);
}
}
});
Ok(())
}
pub fn cmd_change_log_level(
&self,
rest: Option<String>,
callback: UICallback,
) -> Result<(), String> {
trace!("CommandProcessor::cmd_change_log_level");
let mut capi = self.capi();
let ui = self.ui();
spawn_detached_local(async move {
let (layer, rest) = Self::word_split(&rest.unwrap_or_default());
let log_level = match convert_loglevel(&rest.unwrap_or_default()) {
Ok(v) => v,
Err(e) => {
error!("failed to change log level: {}", e);
ui.send_callback(callback);
return;
}
};
match capi.server_change_log_level(layer, log_level).await {
Ok(()) => {
info!("Log level changed");
ui.send_callback(callback);
}
Err(e) => {
error!("Server command 'change_log_level' failed: {}", e);
ui.send_callback(callback);
}
}
@@ -190,6 +237,7 @@ debug - send a debugging command to the Veilid server
"attach" => self.cmd_attach(callback),
"detach" => self.cmd_detach(callback),
"debug" => self.cmd_debug(rest, callback),
"change_log_level" => self.cmd_change_log_level(rest, callback),
_ => {
let ui = self.ui();
ui.send_callback(callback);