From 9118007e1cc97b1211814babe43c5f183ac3bea6 Mon Sep 17 00:00:00 2001 From: bnaruo Date: Fri, 14 Jul 2023 14:54:49 -0400 Subject: [PATCH 01/21] test live update --- .../policy/file-logging/Cargo.toml | 14 + .../policy/file-logging/src/control_plane.rs | 14 + .../policy/file-logging/src/lib.rs | 1 + .../plugin/policy/file-logging/Cargo.toml | 28 ++ .../plugin/policy/file-logging/src/config.rs | 39 +++ .../plugin/policy/file-logging/src/engine.rs | 267 ++++++++++++++++++ .../plugin/policy/file-logging/src/lib.rs | 39 +++ .../plugin/policy/file-logging/src/module.rs | 106 +++++++ .../plugin/policy/file-logging/src/proto.rs | 29 ++ 9 files changed, 537 insertions(+) create mode 100644 experimental/mrpc/phoenix-api/policy/file-logging/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/file-logging/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/file-logging/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/file-logging/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/file-logging/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/file-logging/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/file-logging/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/file-logging/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/file-logging/src/proto.rs diff --git a/experimental/mrpc/phoenix-api/policy/file-logging/Cargo.toml b/experimental/mrpc/phoenix-api/policy/file-logging/Cargo.toml new file mode 100644 index 00000000..9240b465 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/file-logging/Cargo.toml @@ -0,0 +1,14 @@ + +[package] +name = "phoenix-api-policy-file-logging" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true +itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/file-logging/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/file-logging/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/file-logging/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/file-logging/src/lib.rs b/experimental/mrpc/phoenix-api/policy/file-logging/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/file-logging/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/plugin/policy/file-logging/Cargo.toml b/experimental/mrpc/plugin/policy/file-logging/Cargo.toml new file mode 100644 index 00000000..ab006d87 --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/Cargo.toml @@ -0,0 +1,28 @@ + +[package] +name = "phoenix-file-logging" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix_common.workspace = true +phoenix-api-policy-file-logging.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +chrono.workspace = true +itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/plugin/policy/file-logging/src/config.rs b/experimental/mrpc/plugin/policy/file-logging/src/config.rs new file mode 100644 index 00000000..d4094d82 --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/src/config.rs @@ -0,0 +1,39 @@ +use chrono::{Datelike, Timelike, Utc}; +use phoenix_common::log; +use serde::{Deserialize, Serialize}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +use crate::engine::struct_rpc_events_file; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct FileLoggingConfig {} + +impl FileLoggingConfig { + /// Get config from toml file + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} + +pub fn create_log_file() -> std::fs::File { + std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); + let now = Utc::now(); + let date_string = format!( + "{}-{}-{}-{}-{}-{}", + now.year(), + now.month(), + now.day(), + now.hour(), + now.minute(), + now.second() + ); + let file_name = format!("/tmp/phoenix/log/logging_engine_{}.log", date_string); + ///log::info!("create log file {}", file_name); + let log_file = std::fs::File::create(file_name).expect("create file failed"); + log_file +} diff --git a/experimental/mrpc/plugin/policy/file-logging/src/engine.rs b/experimental/mrpc/plugin/policy/file-logging/src/engine.rs new file mode 100644 index 00000000..82168599 --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/src/engine.rs @@ -0,0 +1,267 @@ +use anyhow::{anyhow, Result}; +use futures::future::BoxFuture; +use phoenix_api::rpc::{RpcId, TransportStatus}; +use std::fmt; +use std::fs::File; +use std::io::Write; +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; + +use phoenix_api_policy_file_logging::control_plane; + +use phoenix_common::engine::datapath::message::{ + EngineRxMessage, EngineTxMessage, RpcMessageGeneral, +}; + +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; + +use phoenix_common::engine::datapath::RpcMessageTx; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::{create_log_file, FileLoggingConfig}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub mod hello { + include!("proto.rs"); +} + +pub struct struct_rpc_events_file { + pub timestamp: DateTime, + pub event_type: String, + pub source: String, + pub destination: String, + pub rpc: String, +} +impl struct_rpc_events_file { + pub fn new( + timestamp: DateTime, + event_type: String, + source: String, + destination: String, + rpc: String, + ) -> struct_rpc_events_file { + struct_rpc_events_file { + timestamp: timestamp, + event_type: event_type, + source: source, + destination: destination, + rpc: rpc, + } + } +} + +impl fmt::Display for struct_rpc_events_file { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.timestamp); + write!(f, "{}", self.event_type); + write!(f, "{}", self.source); + write!(f, "{}", self.destination); + write!(f, "{}", self.rpc); + write!(f, "\n") + } +} + +pub(crate) struct FileLoggingEngine { + pub(crate) node: DataPathNode, + pub(crate) indicator: Indicator, + pub(crate) config: FileLoggingConfig, + pub(crate) file_rpc_events_file: File, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for FileLoggingEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "FileLoggingEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + self.config = FileLoggingConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(FileLoggingEngine, node); + +impl Decompose for FileLoggingEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + let mut collections = ResourceCollection::with_capacity(4); + collections.insert("config".to_string(), Box::new(engine.config)); + (collections, engine.node) + } +} + +impl FileLoggingEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let mut file_rpc_events_file = create_log_file(); + let engine = FileLoggingEngine { + node, + indicator: Default::default(), + config, + file_rpc_events_file, + }; + Ok(engine) + } +} + +impl FileLoggingEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + self.indicator.set_nwork(work); + future::yield_now().await; + } + } +} + +#[inline] +fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_ref().unwrap() }; + return req; +} + +impl FileLoggingEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + let mut input = Vec::new(); + input.push(msg); + for event in input + .iter() + .map(|req| { + struct_rpc_events_file::new( + Utc::now(), + format!("{:?}", meta_ref.msg_type), + format!("{:?}", meta_ref.conn_id), + format!("{:?}", meta_ref.conn_id), + format!("{}", req.addr_backend.clone()), + ) + }) + .collect::>() + { + write!(self.file_rpc_events_file, "{}", event); + } + let output: Vec<_> = input + .iter() + .map(|req| { + RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage( + RpcMessageTx::new( + req.meta_buf_ptr.clone(), + req.addr_backend.clone(), + ), + )) + }) + .collect::>(); + + for msg in output { + match msg { + RpcMessageGeneral::TxMessage(msg) => { + self.tx_outputs()[0].send(msg)?; + } + RpcMessageGeneral::RxMessage(msg) => { + self.rx_outputs()[0].send(msg)?; + } + _ => {} + } + } + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineRxMessage::Ack(rpc_id, status) => { + // todo + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + EngineRxMessage::RpcMessage(msg) => { + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => self.rx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/file-logging/src/lib.rs b/experimental/mrpc/plugin/policy/file-logging/src/lib.rs new file mode 100644 index 00000000..64ba3b48 --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/src/lib.rs @@ -0,0 +1,39 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] +use thiserror::Error; + +use crate::engine::struct_rpc_events_file; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::FileLoggingConfig; +use crate::module::FileLoggingAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = FileLoggingConfig::new(config_string)?; + let addon = FileLoggingAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/file-logging/src/module.rs b/experimental/mrpc/plugin/policy/file-logging/src/module.rs new file mode 100644 index 00000000..ab5ce3bd --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/src/module.rs @@ -0,0 +1,106 @@ +use anyhow::{bail, Result}; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::FileLoggingEngine; +use crate::config::{create_log_file, FileLoggingConfig}; +use crate::engine::struct_rpc_events_file; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub(crate) struct FileLoggingEngineBuilder { + node: DataPathNode, + config: FileLoggingConfig, +} + +impl FileLoggingEngineBuilder { + fn new(node: DataPathNode, config: FileLoggingConfig) -> Self { + FileLoggingEngineBuilder { node, config } + } + // TODO! LogFile + fn build(self) -> Result { + let mut file_rpc_events_file = create_log_file(); + Ok(FileLoggingEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + file_rpc_events_file, + }) + } +} + +pub struct FileLoggingAddon { + config: FileLoggingConfig, +} + +impl FileLoggingAddon { + pub const FILE_LOGGING_ENGINE: EngineType = EngineType("FileLoggingEngine"); + pub const ENGINES: &'static [EngineType] = &[FileLoggingAddon::FILE_LOGGING_ENGINE]; +} + +impl FileLoggingAddon { + pub fn new(config: FileLoggingConfig) -> Self { + FileLoggingAddon { config } + } +} + +impl PhoenixAddon for FileLoggingAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + FileLoggingAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != FileLoggingAddon::FILE_LOGGING_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = FileLoggingEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != FileLoggingAddon::FILE_LOGGING_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = FileLoggingEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/file-logging/src/proto.rs b/experimental/mrpc/plugin/policy/file-logging/src/proto.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/file-logging/src/proto.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } From 5cc7bf094343bc09cef9fc30c3fc33309f604989 Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 16 Jul 2023 18:43:40 -0400 Subject: [PATCH 02/21] update --- Makefile.toml | 2 +- experimental/mrpc/.gitignore | 1 + experimental/mrpc/Makefile.toml | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index e3a1fc8f..b7a9b44f 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -22,7 +22,7 @@ dependencies = [ "build-phoenixos", "build-plugins", "deploy-plugins", - "run-phoenixos", + # "run-phoenixos", ] [tasks.phoenix_common] diff --git a/experimental/mrpc/.gitignore b/experimental/mrpc/.gitignore index 2f7896d1..c2458ffa 100644 --- a/experimental/mrpc/.gitignore +++ b/experimental/mrpc/.gitignore @@ -1 +1,2 @@ target/ +generated/* \ No newline at end of file diff --git a/experimental/mrpc/Makefile.toml b/experimental/mrpc/Makefile.toml index 1be09122..a288842f 100644 --- a/experimental/mrpc/Makefile.toml +++ b/experimental/mrpc/Makefile.toml @@ -11,7 +11,7 @@ You can customize your own developmenet testing flow. Build and deploy mRPC plugins. Build and deploy phoenix plugins. Run phoenix daemon. ''' dependencies = [ - "build-phoenixos", + # "build-phoenixos", "build-mrpc-plugins", "build-plugins", "deploy-mrpc-plugins", @@ -39,7 +39,7 @@ args = [ "--manifest-path", "${PROJECT_ROOT}/experimental/mrpc/Cargo.toml", "-p", - "phoenix-*", + "phoenix-${@}", ] # dependencies = ["remove-fingerprint4"] From 65ea2e2908668e3c9edb5bfa8a6c6bef56eb3d8b Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 16 Jul 2023 20:03:11 -0400 Subject: [PATCH 03/21] update make file --- experimental/mrpc/Makefile.toml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/experimental/mrpc/Makefile.toml b/experimental/mrpc/Makefile.toml index a288842f..e72a9e13 100644 --- a/experimental/mrpc/Makefile.toml +++ b/experimental/mrpc/Makefile.toml @@ -18,6 +18,28 @@ dependencies = [ "build-mrpc-examples", "run-phoenixos", ] +[tasks.build-mrpc-plugin-single] +description = ''' +Build specified plugins by package name. +If no argument is provided, build all plugins in this workspace. +''' +# cargo make build-plugins [package-name]* +command = "${TARGET_DIR}/release/phoenix_cargo" +args = [ + "--compile-log", + "${PHOENIX_COMPILE_LOG}", + "--host-dep", + "${HOST_DEP}", + "--", + "build", + "--release", + "--target-dir", + "${PHOENIX_TARGET_DIR}", + "--manifest-path", + "${PROJECT_ROOT}/experimental/mrpc/Cargo.toml", + "-p", + "phoenix-${@}", +] [tasks.build-mrpc-plugins] description = ''' @@ -39,7 +61,7 @@ args = [ "--manifest-path", "${PROJECT_ROOT}/experimental/mrpc/Cargo.toml", "-p", - "phoenix-${@}", + "phoenix-*", ] # dependencies = ["remove-fingerprint4"] From da76e87ea07d943838a917d6f3893db7b8f9d7a1 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 17 Jul 2023 14:22:35 -0400 Subject: [PATCH 04/21] remove rdma --- src/rdma/src/ibv.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/rdma/src/ibv.rs b/src/rdma/src/ibv.rs index 6aa0ddba..70e246cc 100644 --- a/src/rdma/src/ibv.rs +++ b/src/rdma/src/ibv.rs @@ -190,21 +190,21 @@ impl<'devlist> Device<'devlist> { } } - /// Returns stable IB device index as it is assigned by the kernel - /// # Errors - /// - /// - `ENOTSUP`: Stable index is not supported - pub fn index(&self) -> io::Result { - let idx = unsafe { ffi::ibv_get_device_index(*self.0) }; - if idx == -1 { - Err(io::Error::new( - io::ErrorKind::Unsupported, - "device index not known", - )) - } else { - Ok(idx) - } - } + // /// Returns stable IB device index as it is assigned by the kernel + // /// # Errors + // /// + // /// - `ENOTSUP`: Stable index is not supported + // pub fn index(&self) -> io::Result { + // let idx = unsafe { ffi::ibv_get_device_index(*self.0) }; + // if idx == -1 { + // Err(io::Error::new( + // io::ErrorKind::Unsupported, + // "device index not known", + // )) + // } else { + // Ok(idx) + // } + // } } /// An RDMA context bound to a device. From 1ed63a30542d541422895b8898ea6589bec6bd51 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 17 Jul 2023 17:15:31 -0400 Subject: [PATCH 05/21] update phoenix --- phoenix.toml | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/phoenix.toml b/phoenix.toml index be489c0d..8b77e6f4 100644 --- a/phoenix.toml +++ b/phoenix.toml @@ -55,3 +55,103 @@ lib_path = "plugins/libphoenix_salloc.rlib" # requests_per_sec = 1000 # bucket_size = 1000 # ''' +[[modules]] +name = "Mrpc" +lib_path = "plugins/libphoenix_mrpc.rlib" +config_string = ''' +prefix = "/tmp/phoenix" +engine_basename = "mrpc-engine" +build_cache = "/tmp/phoenix/build-cache" +transport = "Rdma" +nic_index = 0 +''' + +[[modules]] +name = "RpcAdapter" +lib_path = "plugins/libphoenix_rpc_adapter.rlib" +config_string = ''' +enable_scheduler = false +''' + + +[[modules]] +name = "TcpRpcAdapter" +lib_path = "plugins/libphoenix_tcp_rpc_adapter.rlib" + + +[[addons]] +name = "RateLimit" +lib_path = "plugins/libphoenix_ratelimit.rlib" +config_string = ''' +requests_per_sec = 1000 +bucket_size = 1000 +''' + +[[addons]] +name = "Qos" +lib_path = "plugins/libphoenix_qos.rlib" +config_string = ''' +latency_budget_microsecs = 10 +''' + +[[addons]] +name = "HotelAcl" +lib_path = "plugins/libphoenix_hotel_acl.rlib" +config_string = ''' +''' + +[[addons]] +name = "Null" +lib_path = "plugins/libphoenix_null.rlib" +config_string = ''' +''' + +[[addons]] +name = "logging" +lib_path = "plugins/libphoenix_logging.rlib" +config_string = ''' +''' + +[[addons]] +name = "HelloAclReceiver" +lib_path = "plugins/libphoenix_hello_acl_receiver.rlib" +config_string = ''' +''' + +[[addons]] +name = "HelloAclSender" +lib_path = "plugins/libphoenix_hello_acl_sender.rlib" +config_string = ''' +''' + +[[addons]] +name = "HelloAcl" +lib_path = "plugins/libphoenix_hello_acl.rlib" +config_string = ''' +''' + +[[addons]] +name = "NofileLogging" +lib_path = "plugins/libphoenix_nofile_logging.rlib" +config_string = ''' +''' + +[[addons]] +name = "Fault" +lib_path = "plugins/libphoenix_fault.rlib" +config_string = ''' +''' + +[[addons]] +name = "Fault2" +lib_path = "plugins/libphoenix_fault2.rlib" +config_string = ''' +''' + +[[addons]] +name = "Delay" +lib_path = "plugins/libphoenix_delay.rlib" +config_string = ''' +delay_probability = 0.2 +delay_ms = 100 +''' From 7cd3fcda8a103777981525612eef887da3a80e5d Mon Sep 17 00:00:00 2001 From: banruo Date: Wed, 26 Jul 2023 18:27:30 -0400 Subject: [PATCH 06/21] update ratelimt drop --- eval/policy/ratelimit-drop/attach.toml | 35 +++ eval/policy/ratelimit-drop/detach.toml | 4 + experimental/mrpc/Cargo.lock | 31 +++ experimental/mrpc/Cargo.toml | 3 + experimental/mrpc/load-mrpc-plugins.toml | 8 + .../policy/ratelimit-drop/Cargo.toml | 11 + .../ratelimit-drop/src/control_plane.rs | 14 + .../policy/ratelimit-drop/src/lib.rs | 1 + .../plugin/policy/ratelimit-drop/Cargo.toml | 26 ++ .../policy/ratelimit-drop/src/config.rs | 24 ++ .../policy/ratelimit-drop/src/engine.rs | 260 ++++++++++++++++++ .../plugin/policy/ratelimit-drop/src/lib.rs | 32 +++ .../policy/ratelimit-drop/src/module.rs | 104 +++++++ .../plugin/policy/ratelimit-drop/src/proto.rs | 29 ++ phoenix.toml | 8 + 15 files changed, 590 insertions(+) create mode 100644 eval/policy/ratelimit-drop/attach.toml create mode 100644 eval/policy/ratelimit-drop/detach.toml create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop/src/proto.rs diff --git a/eval/policy/ratelimit-drop/attach.toml b/eval/policy/ratelimit-drop/attach.toml new file mode 100644 index 00000000..3aae53ac --- /dev/null +++ b/eval/policy/ratelimit-drop/attach.toml @@ -0,0 +1,35 @@ +addon_engine = "RateLimitDropEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "RateLimitDropEngine", + 0, + 0, + ], + [ + "RateLimitDropEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "RateLimitDropEngine", + 0, + 0, + ], + [ + "RateLimitDropEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +requests_per_sec = 2 +bucket_size = 10 +''' diff --git a/eval/policy/ratelimit-drop/detach.toml b/eval/policy/ratelimit-drop/detach.toml new file mode 100644 index 00000000..fcd8f868 --- /dev/null +++ b/eval/policy/ratelimit-drop/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "RateLimitDropEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] +op = "detach" diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index cc3b30c7..d64070f7 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1700,6 +1700,14 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-ratelimit-drop" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-rpc-adapter" version = "0.1.0" @@ -2045,6 +2053,29 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-ratelimit-drop" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-ratelimit-drop", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-rpc-adapter" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 2083f5f9..6f8ae229 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -49,6 +49,7 @@ members = [ "phoenix-api/tcp_rpc_adapter", "phoenix-api/policy/null", "phoenix-api/policy/ratelimit", + "phoenix-api/policy/ratelimit-drop", "phoenix-api/policy/qos", "phoenix-api/policy/hotel-acl", "phoenix-api/policy/logging", @@ -66,6 +67,7 @@ members = [ # TODO(cjr): Add them back "plugin/policy/null", "plugin/policy/ratelimit", + "plugin/policy/ratelimit-drop", "plugin/policy/qos", "plugin/policy/logging", "plugin/policy/hotel-acl", @@ -94,6 +96,7 @@ phoenix-api-tcp-rpc-adapter = { path = "phoenix-api/tcp_rpc_adapter" } phoenix-api-rpc-adapter = { path = "phoenix-api/rpc_adapter" } phoenix-api-policy-null = { path = "phoenix-api/policy/null" } phoenix-api-policy-ratelimit = { path = "phoenix-api/policy/ratelimit" } +phoenix-api-policy-ratelimit-drop = { path = "phoenix-api/policy/ratelimit-drop" } phoenix-api-policy-qos = { path = "phoenix-api/policy/qos" } phoenix-api-policy-hotel-acl = { path = "phoenix-api/policy/hotel-acl" } phoenix-api-policy-logging = { path = "phoenix-api/policy/logging" } diff --git a/experimental/mrpc/load-mrpc-plugins.toml b/experimental/mrpc/load-mrpc-plugins.toml index d7e68f54..51e54cc8 100644 --- a/experimental/mrpc/load-mrpc-plugins.toml +++ b/experimental/mrpc/load-mrpc-plugins.toml @@ -98,3 +98,11 @@ config_string = ''' delay_probability = 0.2 delay_ms = 100 ''' + +[[addons]] +name = "RateLimitDrop" +lib_path = "plugins/libphoenix_ratelimit_drop.rlib" +config_string = ''' +requests_per_sec = 4 +bucket_size = 1000 +''' diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop/Cargo.toml b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/Cargo.toml new file mode 100644 index 00000000..743b0d4b --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-ratelimit-drop" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/control_plane.rs new file mode 100644 index 00000000..dc317e5f --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(u64, u64), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/lib.rs b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/Cargo.toml b/experimental/mrpc/plugin/policy/ratelimit-drop/Cargo.toml new file mode 100644 index 00000000..4b592492 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "phoenix-ratelimit-drop" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix_common.workspace = true +phoenix-api-policy-ratelimit-drop.workspace = true + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } +chrono.workspace = true +itertools.workspace = true diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/config.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/config.rs new file mode 100644 index 00000000..7f4af438 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/config.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct RateLimitDropConfig { + pub requests_per_sec: u64, + pub bucket_size: u64, +} + +impl Default for RateLimitDropConfig { + fn default() -> Self { + RateLimitDropConfig { + requests_per_sec: 100000, + bucket_size: 100000, + } + } +} + +impl RateLimitDropConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs new file mode 100644 index 00000000..cd807fe7 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs @@ -0,0 +1,260 @@ +use std::collections::VecDeque; +use std::os::unix::ucred::UCred; +use std::pin::Pin; + +use super::DatapathError; +use crate::config::RateLimitDropConfig; +use anyhow::{anyhow, Result}; +use futures::future::BoxFuture; +use minstant::Instant; +use phoenix_api::rpc::{RpcId, TransportStatus}; +use phoenix_api_policy_ratelimit_drop::control_plane; +use phoenix_common::engine::datapath::message::{EngineTxMessage, RpcMessageGeneral, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::datapath::EngineRxMessage; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; +use std::num::NonZeroU32; + +pub mod hello { + include!("proto.rs"); +} + +fn hello_request_name_readonly(req: &hello::HelloRequest) -> String { + let buf = &req.name as &[u8]; + String::from_utf8_lossy(buf).to_string().clone() +} + +pub(crate) struct RateLimitDropEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + // A set of func_ids to apply the rate limit. + // TODO(cjr): maybe put this filter in a separate engine like FilterEngine/ClassiferEngine. + // pub(crate) filter: FnvHashSet, + // Number of tokens to add for each seconds. + pub(crate) config: RateLimitDropConfig, + // The most recent timestamp we add the token to the bucket. + pub(crate) last_ts: Instant, + // The number of available tokens in the token bucket algorithm. + pub(crate) num_tokens: f64, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for RateLimitDropEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "RateLimitDropEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig(requests_per_sec, bucket_size) => { + self.config = RateLimitDropConfig { + requests_per_sec, + bucket_size, + }; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(RateLimitDropEngine, node); + +impl Decompose for RateLimitDropEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(4); + collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("last_ts".to_string(), Box::new(engine.last_ts)); + collections.insert("num_tokens".to_string(), Box::new(engine.num_tokens)); + (collections, engine.node) + } +} + +impl RateLimitDropEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let last_ts: Instant = *local + .remove("last_ts") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_tokens = *local + .remove("num_tokens") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let engine = RateLimitDropEngine { + node, + indicator: Default::default(), + config, + last_ts, + num_tokens, + }; + Ok(engine) + } +} + +impl RateLimitDropEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +fn current_timestamp() -> Instant { + Instant::now() +} + +#[inline] +fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_ref().unwrap() }; + return req; +} + +impl RateLimitDropEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + let mut input = Vec::new(); + input.push(msg); + self.num_tokens = self.num_tokens + + (current_timestamp() - self.last_ts).as_secs_f64() + * self.config.requests_per_sec as f64; + self.last_ts = current_timestamp(); + log::debug!("num_tokens: {}", self.num_tokens); + let limit = std::cmp::min(input.len() as i64, self.num_tokens as i64); + self.num_tokens = self.num_tokens - limit as f64; + + let output = input.iter().enumerate().map(|(index, req)| { + let rpc_message = materialize_nocopy(&req); + let conn_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.call_id; + let rpc_id = RpcId::new(conn_id, call_id); + if index < limit as usize { + let raw_ptr: *const hello::HelloRequest = rpc_message; + let new_msg = RpcMessageTx { + meta_buf_ptr: req.meta_buf_ptr.clone(), + addr_backend: req.addr_backend, + }; + RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage(new_msg)) + } else { + let error = EngineRxMessage::Ack( + rpc_id, + TransportStatus::Error(unsafe { + NonZeroU32::new_unchecked(403) + }), + ); + RpcMessageGeneral::RxMessage(error) + } + }); + for msg in output { + match msg { + RpcMessageGeneral::TxMessage(msg) => { + self.tx_outputs()[0].send(msg)?; + } + RpcMessageGeneral::RxMessage(msg) => { + self.rx_outputs()[0].send(msg)?; + } + _ => {} + } + } + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineRxMessage::Ack(rpc_id, status) => { + // todo + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + EngineRxMessage::RpcMessage(msg) => { + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => self.rx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/lib.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/lib.rs new file mode 100644 index 00000000..11be89f9 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/lib.rs @@ -0,0 +1,32 @@ +#![feature(peer_credentials_unix_socket)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::RateLimitDropConfig; +use crate::module::RateLimitDropAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = RateLimitDropConfig::new(config_string)?; + let addon = RateLimitDropAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/module.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/module.rs new file mode 100644 index 00000000..156ee473 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/module.rs @@ -0,0 +1,104 @@ +use std::collections::VecDeque; + +use anyhow::{bail, Result}; +use minstant::Instant; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::RateLimitDropEngine; +use crate::config::RateLimitDropConfig; + +pub(crate) struct RateLimitDropEngineBuilder { + node: DataPathNode, + config: RateLimitDropConfig, +} + +impl RateLimitDropEngineBuilder { + fn new(node: DataPathNode, config: RateLimitDropConfig) -> Self { + RateLimitDropEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(RateLimitDropEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + last_ts: Instant::now(), + num_tokens: self.config.bucket_size as _, + }) + } +} + +pub struct RateLimitDropAddon { + config: RateLimitDropConfig, +} + +impl RateLimitDropAddon { + pub const RATE_LIMIT_DROP_ENGINE: EngineType = EngineType("RateLimitDropEngine"); + pub const ENGINES: &'static [EngineType] = &[RateLimitDropAddon::RATE_LIMIT_DROP_ENGINE]; +} + +impl RateLimitDropAddon { + pub fn new(config: RateLimitDropConfig) -> Self { + RateLimitDropAddon { config } + } +} + +impl PhoenixAddon for RateLimitDropAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + RateLimitDropAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != RateLimitDropAddon::RATE_LIMIT_DROP_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = RateLimitDropEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != RateLimitDropAddon::RATE_LIMIT_DROP_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = RateLimitDropEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/proto.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/proto.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/proto.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } diff --git a/phoenix.toml b/phoenix.toml index 8b77e6f4..032a4340 100644 --- a/phoenix.toml +++ b/phoenix.toml @@ -155,3 +155,11 @@ config_string = ''' delay_probability = 0.2 delay_ms = 100 ''' + +[[addons]] +name = "RateLimitDrop" +lib_path = "plugins/libphoenix_ratelimit_drop.rlib" +config_string = ''' +requests_per_sec = 4 +bucket_size = 1000 +''' From 32c15ceb7113dd9e05f18769c0bbb45de7f48b8a Mon Sep 17 00:00:00 2001 From: Banruo Liu Date: Thu, 7 Sep 2023 15:58:23 -0700 Subject: [PATCH 07/21] Basic Load Balancer Functionality (#239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * example * backup mrpc engine * template for lb * try * remove addon * connected control path, in a ad hoc way * update * it works 😃 * finish connect * it worked🥵 * refactor * work work * refactor * fix * fix trivial --- experimental/mrpc/Cargo.lock | 92 +++ experimental/mrpc/Cargo.toml | 8 + .../mrpc/examples/load_balancer/Cargo.toml | 25 + .../mrpc/examples/load_balancer/README.md | 24 + .../mrpc/examples/load_balancer/build.rs | 6 + .../mrpc/examples/load_balancer/src/client.rs | 63 ++ .../mrpc/examples/load_balancer/src/server.rs | 58 ++ experimental/mrpc/load-mrpc-plugins.toml | 16 +- experimental/mrpc/mrpc-build/src/client.rs | 14 +- .../mrpc/phoenix-api/load_balancer/Cargo.toml | 11 + .../load_balancer/src/control_plane.rs | 26 + .../mrpc/phoenix-api/load_balancer/src/lib.rs | 1 + experimental/mrpc/phoenix-api/mrpc/src/cmd.rs | 4 + .../phoenix-api/mrpc/src/control_plane.rs | 2 + .../mrpc/phoenix-api/mrpclb/Cargo.toml | 12 + .../mrpc/phoenix-api/mrpclb/src/cmd.rs | 59 ++ .../phoenix-api/mrpclb/src/control_plane.rs | 49 ++ .../mrpc/phoenix-api/mrpclb/src/dp.rs | 39 ++ .../mrpc/phoenix-api/mrpclb/src/lib.rs | 3 + .../mrpc/plugin/load_balancer/Cargo.toml | 39 ++ .../mrpc/plugin/load_balancer/src/engine.rs | 428 ++++++++++++ .../mrpc/plugin/load_balancer/src/lib.rs | 93 +++ .../mrpc/plugin/load_balancer/src/module.rs | 235 +++++++ experimental/mrpc/plugin/mrpc/src/engine.rs | 3 + experimental/mrpc/plugin/mrpc/src/module.rs | 4 +- experimental/mrpc/plugin/mrpclb/Cargo.toml | 39 ++ .../mrpc/plugin/mrpclb/src/builder/cache.rs | 61 ++ .../src/builder/compiler/code_generator.rs | 120 ++++ .../plugin/mrpclb/src/builder/compiler/mod.rs | 101 +++ .../src/builder/compiler/template/Cargo.toml | 13 + .../mrpc/plugin/mrpclb/src/builder/mod.rs | 173 +++++ .../plugin/mrpclb/src/builder/prost/mod.rs | 16 + .../plugin/mrpclb/src/builder/prost/prost.rs | 218 +++++++ .../mrpclb/src/builder/prost/service.rs | 112 ++++ experimental/mrpc/plugin/mrpclb/src/config.rs | 39 ++ experimental/mrpc/plugin/mrpclb/src/engine.rs | 616 ++++++++++++++++++ experimental/mrpc/plugin/mrpclb/src/lib.rs | 78 +++ experimental/mrpc/plugin/mrpclb/src/module.rs | 341 ++++++++++ experimental/mrpc/plugin/mrpclb/src/state.rs | 32 + experimental/mrpc/plugin/mrpclb/src/unpack.rs | 26 + .../mrpc/plugin/rpc_adapter/src/engine.rs | 3 + .../mrpc/plugin/rpc_adapter/src/module.rs | 2 +- .../mrpc/plugin/tcp_rpc_adapter/src/engine.rs | 4 + .../mrpc/plugin/tcp_rpc_adapter/src/module.rs | 5 +- experimental/mrpc/src/lib.rs | 7 +- experimental/mrpc/src/rheap.rs | 7 + experimental/mrpc/src/stub/client.rs | 130 +++- experimental/mrpc/src/stub/conn.rs | 9 + src/phoenix-api/core/src/handle.rs | 4 + src/phoenixos/src/control.rs | 4 +- 50 files changed, 3452 insertions(+), 22 deletions(-) create mode 100644 experimental/mrpc/examples/load_balancer/Cargo.toml create mode 100644 experimental/mrpc/examples/load_balancer/README.md create mode 100644 experimental/mrpc/examples/load_balancer/build.rs create mode 100644 experimental/mrpc/examples/load_balancer/src/client.rs create mode 100644 experimental/mrpc/examples/load_balancer/src/server.rs create mode 100644 experimental/mrpc/phoenix-api/load_balancer/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/load_balancer/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/load_balancer/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/mrpclb/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/mrpclb/src/cmd.rs create mode 100644 experimental/mrpc/phoenix-api/mrpclb/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/mrpclb/src/dp.rs create mode 100644 experimental/mrpc/phoenix-api/mrpclb/src/lib.rs create mode 100644 experimental/mrpc/plugin/load_balancer/Cargo.toml create mode 100644 experimental/mrpc/plugin/load_balancer/src/engine.rs create mode 100644 experimental/mrpc/plugin/load_balancer/src/lib.rs create mode 100644 experimental/mrpc/plugin/load_balancer/src/module.rs create mode 100644 experimental/mrpc/plugin/mrpclb/Cargo.toml create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/cache.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/compiler/code_generator.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/compiler/mod.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/compiler/template/Cargo.toml create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/mod.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/prost/mod.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/prost/prost.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/builder/prost/service.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/config.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/engine.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/lib.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/module.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/state.rs create mode 100644 experimental/mrpc/plugin/mrpclb/src/unpack.rs diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 42e6f386..826584cc 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1064,6 +1064,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lb" +version = "0.1.0" +dependencies = [ + "mrpc", + "mrpc-build", + "prost", + "smol", + "structopt", +] + [[package]] name = "libc" version = "0.2.136" @@ -1586,6 +1597,14 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "phoenix-api-load-balancer" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-mrpc" version = "0.1.0" @@ -1595,6 +1614,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "phoenix-api-mrpclb" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", + "static_assertions", +] + [[package]] name = "phoenix-api-policy-hello-acl-receiver" version = "0.1.0" @@ -1771,6 +1799,38 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-load-balancer" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "bitvec", + "dashmap", + "fastrand", + "fnv", + "futures", + "ipc", + "libloading", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-load-balancer", + "phoenix-api-mrpc", + "phoenix-mrpc", + "phoenix-salloc", + "phoenix-transport-tcp", + "phoenix_common", + "serde", + "slab", + "socket2", + "spin", + "thiserror", + "tokio", + "toml", + "utils", +] + [[package]] name = "phoenix-logging" version = "0.1.0" @@ -1821,6 +1881,38 @@ dependencies = [ "uuid", ] +[[package]] +name = "phoenix-mrpclb" +version = "0.1.0" +dependencies = [ + "anyhow", + "crc32fast", + "fastrand", + "fnv", + "futures", + "ipc", + "itertools", + "lazy_static", + "md5", + "mrpc-marshal", + "phoenix-api", + "phoenix-api-mrpc", + "phoenix_common", + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "serde", + "serde_json", + "static_assertions", + "syn", + "thiserror", + "tokio", + "toml", + "utils", + "uuid", +] + [[package]] name = "phoenix-null" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index aa028b82..8979240a 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -45,8 +45,10 @@ members = [ "mrpc-marshal", # extension to phoenix-api "phoenix-api/mrpc", + "phoenix-api/mrpclb", "phoenix-api/rpc_adapter", "phoenix-api/tcp_rpc_adapter", + "phoenix-api/load_balancer", "phoenix-api/policy/null", "phoenix-api/policy/ratelimit", "phoenix-api/policy/qos", @@ -56,8 +58,10 @@ members = [ "phoenix-api/policy/hello-acl-sender", # the pheonix plugins "plugin/mrpc", + "plugin/mrpclb", "plugin/rpc_adapter", "plugin/tcp_rpc_adapter", + "plugin/load_balancer", # TODO(cjr): Add them back "plugin/policy/null", "plugin/policy/ratelimit", @@ -72,6 +76,7 @@ members = [ "examples/rpc_bench_plus", "examples/masstree_analytics", "examples/hotel_reservation", + "examples/load_balancer", # "examples/hotel_microservices", ] exclude = ["3rdparty/prost"] @@ -80,8 +85,10 @@ exclude = ["3rdparty/prost"] [workspace.dependencies] mrpc = { path = "." } phoenix-api-mrpc = { path = "phoenix-api/mrpc" } +phoenix-api-mrpclb = { path = "phoenix-api/mrpclb" } phoenix-api-tcp-rpc-adapter = { path = "phoenix-api/tcp_rpc_adapter" } phoenix-api-rpc-adapter = { path = "phoenix-api/rpc_adapter" } +phoenix-api-load-balancer = { path = "phoenix-api/load_balancer" } phoenix-api-policy-null = { path = "phoenix-api/policy/null" } phoenix-api-policy-ratelimit = { path = "phoenix-api/policy/ratelimit" } phoenix-api-policy-qos = { path = "phoenix-api/policy/qos" } @@ -96,6 +103,7 @@ mrpc-marshal = { path = "mrpc-marshal" } prost = { path = "3rdparty/prost" } prost-build = { path = "3rdparty/prost/prost-build" } phoenix-mrpc = { path = "plugin/mrpc" } +phoenix-mrpclb = { path = "plugin/mrpclb" } phoenix-syscalls = { path = "../../src/phoenix-syscalls" } phoenix-api = { path = "../../src/phoenix-api" } diff --git a/experimental/mrpc/examples/load_balancer/Cargo.toml b/experimental/mrpc/examples/load_balancer/Cargo.toml new file mode 100644 index 00000000..2ade3d5d --- /dev/null +++ b/experimental/mrpc/examples/load_balancer/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "lb" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +mrpc-build.workspace = true + +[dependencies] +mrpc.workspace = true +prost = { workspace = true, features = ["mrpc-frontend"] } + +structopt.workspace = true +smol.workspace = true + + +[[bin]] +name = "server" +path = "src/server.rs" + +[[bin]] +name = "client" +path = "src/client.rs" diff --git a/experimental/mrpc/examples/load_balancer/README.md b/experimental/mrpc/examples/load_balancer/README.md new file mode 100644 index 00000000..de6b2991 --- /dev/null +++ b/experimental/mrpc/examples/load_balancer/README.md @@ -0,0 +1,24 @@ +## Build the application + +```bash +# In phoenix/experimental/mrpc +cargo build --release --workspace -p rpc_hello_frontend +``` + +## Run the application with client + +```bash +cargo rr -p rpc_echo --bin rpc_echo_server +# In a seperate terminal +cargo rr -p rpc_echo --bin rpc_echo_client +``` + +## Run the application with frontend + +```bash +cargo rr -p rpc_echo --bin rpc_echo_server +# In a seperate terminal +cargo rr -p rpc_echo --bin rpc_echo_frontend +# In a seperate terminal +curl http://127.0.0.1:7878/hello +``` \ No newline at end of file diff --git a/experimental/mrpc/examples/load_balancer/build.rs b/experimental/mrpc/examples/load_balancer/build.rs new file mode 100644 index 00000000..28e46283 --- /dev/null +++ b/experimental/mrpc/examples/load_balancer/build.rs @@ -0,0 +1,6 @@ +const PROTO: &str = "../proto/rpc_hello/rpc_hello.proto"; +fn main() -> Result<(), Box> { + println!("cargo:rerun-if-changed={PROTO}"); + mrpc_build::compile_protos(PROTO)?; + Ok(()) +} diff --git a/experimental/mrpc/examples/load_balancer/src/client.rs b/experimental/mrpc/examples/load_balancer/src/client.rs new file mode 100644 index 00000000..6e3cec34 --- /dev/null +++ b/experimental/mrpc/examples/load_balancer/src/client.rs @@ -0,0 +1,63 @@ +pub mod rpc_hello { + // The string specified here must match the proto package name + mrpc::include_proto!("rpc_hello"); + // include!("../../../mrpc/src/codegen.rs"); +} + +use mrpc::stub::TransportType; +use rpc_hello::greeter_client::GreeterClient; +use rpc_hello::HelloRequest; +use std::{env, thread, time::Duration, time::Instant}; + +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + let addrs = args[1..].to_vec(); + println!("MultiConnect to {:?}", addrs); + let mut setting = mrpc::current_setting(); + setting.module_config = Some("MrpcLB".into()); + setting.transport = TransportType::Tcp; + mrpc::set(&setting); + let client = GreeterClient::multi_connect(addrs)?; + println!("Connected to servers!"); + let mut apple_count = 0; + let mut banana_count = 0; + let mut last_print_time = Instant::now(); + let interval = Duration::from_secs(5); + let mut i = 0; + loop { + i = i ^ 1; + let mut req = HelloRequest { + name: "Apple".into(), + }; + if i == 0 { + req = HelloRequest { + name: "Banana".into(), + }; + } + let reply = smol::block_on(client.say_hello(req)); + match reply { + Ok(reply) => { + let reply = String::from_utf8_lossy(&reply.message); + if reply == "Hello Apple!" { + apple_count += 1; + } else { + banana_count += 1; + } + } + Err(e) => { + println!("error: {}", e); + } + } + + thread::sleep(Duration::from_millis(250)); + + let elapsed = Instant::now().duration_since(last_print_time); + if elapsed >= interval { + println!( + "Apple count: {}, Banana count: {}", + apple_count, banana_count + ); + last_print_time = Instant::now(); + } + } +} diff --git a/experimental/mrpc/examples/load_balancer/src/server.rs b/experimental/mrpc/examples/load_balancer/src/server.rs new file mode 100644 index 00000000..12763030 --- /dev/null +++ b/experimental/mrpc/examples/load_balancer/src/server.rs @@ -0,0 +1,58 @@ +//! This code defines a simple mRPC server that implements the Greeter service. +//! It listens for incoming "Hello" requests and sends back a greeting message. + +// Import the auto-generated code for the "rpc_hello" module from the Proto file. +pub mod rpc_echo { + // The string specified here must match the proto package name + mrpc::include_proto!("rpc_hello"); +} + +use rpc_echo::greeter_server::{Greeter, GreeterServer}; +use rpc_echo::{HelloReply, HelloRequest}; +use std::env; + +use mrpc::{RRef, WRef}; + +#[derive(Debug, Default)] +struct MyGreeter; + +// Implement the Greeter trait for MyGreeter using async_trait. +#[mrpc::async_trait] +impl Greeter for MyGreeter { + // Define the say_hello function which takes an RRef + // and returns a Result with a WRef. + async fn say_hello( + &self, + request: RRef, + ) -> Result, mrpc::Status> { + // Log the received request. + eprintln!("request: {:?}", request); + + // Create a new HelloReply with a greeting message. + let message = format!("Hello {}!", String::from_utf8_lossy(&request.name)); + let reply = WRef::new(HelloReply { + message: message.as_bytes().into(), + }); + + Ok(reply) + } +} + +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + assert!(args.len() == 2, "Usage: "); + let addr = args[1].clone(); + println!("Serve on {}", addr); + // Start the server, binding it to port 5000. + smol::block_on(async { + let mut server = mrpc::stub::LocalServer::bind(addr)?; + + // Add the Greeter service to the server using the custom MyGreeter implementation. + server + .add_service(GreeterServer::new(MyGreeter::default())) + .serve() + .await?; + eprintln!("server stopped"); + Ok(()) + }) +} diff --git a/experimental/mrpc/load-mrpc-plugins.toml b/experimental/mrpc/load-mrpc-plugins.toml index 9853d015..1841c039 100644 --- a/experimental/mrpc/load-mrpc-plugins.toml +++ b/experimental/mrpc/load-mrpc-plugins.toml @@ -5,7 +5,18 @@ config_string = ''' prefix = "/tmp/phoenix" engine_basename = "mrpc-engine" build_cache = "/tmp/phoenix/build-cache" -transport = "Rdma" +transport = "Tcp" +nic_index = 0 +''' + +[[modules]] +name = "MrpcLB" +lib_path = "plugins/libphoenix_mrpclb.rlib" +config_string = ''' +prefix = "/tmp/phoenix" +engine_basename = "mrpclb-engine" +build_cache = "/tmp/phoenix/build-cache" +transport = "Tcp" nic_index = 0 ''' @@ -21,6 +32,9 @@ enable_scheduler = false name = "TcpRpcAdapter" lib_path = "plugins/libphoenix_tcp_rpc_adapter.rlib" +[[modules]] +name = "LoadBalancer" +lib_path = "plugins/libphoenix_load_balancer.rlib" [[addons]] name = "RateLimit" diff --git a/experimental/mrpc/mrpc-build/src/client.rs b/experimental/mrpc/mrpc-build/src/client.rs index fc546cc5..de63c894 100644 --- a/experimental/mrpc/mrpc-build/src/client.rs +++ b/experimental/mrpc/mrpc-build/src/client.rs @@ -67,7 +67,19 @@ pub fn generate( stub, }) } - + pub fn multi_connect(dsts: impl IntoIterator) -> Result { + // use the cmid builder to create a CmId. + // no you shouldn't rely on cmid here anymore. you should have your own rpc endpoint + // cmid communicates directly to the transport engine. you need to pass your raw rpc + // request/response to/from the rpc engine rather than the transport engine. + // let stub = phoenix_syscalls::mrpc::cm::MrpcStub::set_transport(phoenix_syscalls::mrpc::cm::TransportType::Rdma)?; + Self::update_protos()?; + let dsts = dsts.into_iter().collect(); + let stub = ClientStub::multi_connect(dsts).unwrap(); + Ok(Self { + stub, + }) + } #methods } diff --git a/experimental/mrpc/phoenix-api/load_balancer/Cargo.toml b/experimental/mrpc/phoenix-api/load_balancer/Cargo.toml new file mode 100644 index 00000000..35cee43b --- /dev/null +++ b/experimental/mrpc/phoenix-api/load_balancer/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-load-balancer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde = { workspace = true, features = ["derive"] } diff --git a/experimental/mrpc/phoenix-api/load_balancer/src/control_plane.rs b/experimental/mrpc/phoenix-api/load_balancer/src/control_plane.rs new file mode 100644 index 00000000..0ab45e43 --- /dev/null +++ b/experimental/mrpc/phoenix-api/load_balancer/src/control_plane.rs @@ -0,0 +1,26 @@ +use std::net::SocketAddr; + +use phoenix_api::Handle; +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + ListConnection, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Connection { + pub sock: Handle, + pub local: SocketAddr, + pub peer: SocketAddr, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind { + ListConnection(Vec), +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/load_balancer/src/lib.rs b/experimental/mrpc/phoenix-api/load_balancer/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/load_balancer/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/mrpc/src/cmd.rs b/experimental/mrpc/phoenix-api/mrpc/src/cmd.rs index 82ea2bfa..4c4c6722 100644 --- a/experimental/mrpc/phoenix-api/mrpc/src/cmd.rs +++ b/experimental/mrpc/phoenix-api/mrpc/src/cmd.rs @@ -12,6 +12,8 @@ type IResult = Result; pub enum Command { SetTransport(TransportType), Connect(SocketAddr), + // MultiConnect tells lb to map a vector of connections to a virtual connection + MultiConnect(Vec), Bind(SocketAddr), // The app notifies the backend with its mapped addresses // conn_handle, [mr_handle, addr] @@ -40,6 +42,8 @@ pub enum CompletionKind { // connection handle, receive mrs ConnectInternal(ConnectResponse, Vec), Connect(ConnectResponse), + // v connect returns the virtual connection handle + MultiConnect(Handle), Bind(Handle), // These are actually commands which go by a reverse direction. // conn_handle, (mr_handle, kaddr, len, file_off) diff --git a/experimental/mrpc/phoenix-api/mrpc/src/control_plane.rs b/experimental/mrpc/phoenix-api/mrpc/src/control_plane.rs index 30308427..ce695d97 100644 --- a/experimental/mrpc/phoenix-api/mrpc/src/control_plane.rs +++ b/experimental/mrpc/phoenix-api/mrpc/src/control_plane.rs @@ -46,4 +46,6 @@ pub struct Setting { /// The core index the user binds to. [`None`] if the user thread does not explicit set a /// scheduling affinity. pub core_id: Option, + + pub module_config: Option, } diff --git a/experimental/mrpc/phoenix-api/mrpclb/Cargo.toml b/experimental/mrpc/phoenix-api/mrpclb/Cargo.toml new file mode 100644 index 00000000..5163b4a4 --- /dev/null +++ b/experimental/mrpc/phoenix-api/mrpclb/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "phoenix-api-mrpclb" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api = { workspace = true, features = ["mrpc"] } + +serde.workspace = true +static_assertions.workspace = true diff --git a/experimental/mrpc/phoenix-api/mrpclb/src/cmd.rs b/experimental/mrpc/phoenix-api/mrpclb/src/cmd.rs new file mode 100644 index 00000000..944d18f8 --- /dev/null +++ b/experimental/mrpc/phoenix-api/mrpclb/src/cmd.rs @@ -0,0 +1,59 @@ +//! mRPClb control path commands. +use std::{net::SocketAddr, os::unix::prelude::RawFd, path::PathBuf}; + +use serde::{Deserialize, Serialize}; + +use super::control_plane::TransportType; +use phoenix_api::Handle; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Command { + SetTransport(TransportType), + Connect(SocketAddr), + // MultiConnect tells lb to map a vector of connections to a virtual connection + MultiConnect(Vec), + Bind(SocketAddr), + // The app notifies the backend with its mapped addresses + // conn_handle, [mr_handle, addr] + NewMappedAddrs(Handle, Vec<(Handle, usize)>), + UpdateProtos(Vec), + UpdateProtosInner(PathBuf), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ReadHeapRegion { + pub handle: Handle, + pub addr: usize, + pub len: usize, + pub file_off: i64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ConnectResponse { + pub conn_handle: Handle, + pub read_regions: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum CompletionKind { + SetTransport, + // connection handle, receive mrs + ConnectInternal(ConnectResponse, Vec), + Connect(ConnectResponse), + // v connect returns the virtual connection handle + MultiConnect(Handle), + Bind(Handle), + // These are actually commands which go by a reverse direction. + // conn_handle, (mr_handle, kaddr, len, file_off) + // TODO(wyj): pass align + NewConnectionInternal(ConnectResponse, Vec), + NewConnection(ConnectResponse), + // the acknowledgement + NewMappedAddrs, + UpdateProtos, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Completion(pub IResult); diff --git a/experimental/mrpc/phoenix-api/mrpclb/src/control_plane.rs b/experimental/mrpc/phoenix-api/mrpclb/src/control_plane.rs new file mode 100644 index 00000000..30308427 --- /dev/null +++ b/experimental/mrpc/phoenix-api/mrpclb/src/control_plane.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +/// A list of supported underlying transports to use. +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] +pub enum TransportType { + #[serde(alias = "Rdma")] + Rdma, + #[default] + #[serde(alias = "Tcp")] + Tcp, +} + +impl std::str::FromStr for TransportType { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s.to_uppercase().as_str() { + "RDMA" => Ok(Self::Rdma), + "TCP" => Ok(Self::Tcp), + _ => Err("Expect RDMA or TCP"), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request {} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); + +/// mRPC service setting. +/// +/// Each user thread can have its own service setting. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] +pub struct Setting { + /// The transport to use. + pub transport: TransportType, + /// The NIC to use. TODO(cjr): choose a better configuration option rather than explicitly + /// seting the NIC. + pub nic_index: usize, + /// The core index the user binds to. [`None`] if the user thread does not explicit set a + /// scheduling affinity. + pub core_id: Option, +} diff --git a/experimental/mrpc/phoenix-api/mrpclb/src/dp.rs b/experimental/mrpc/phoenix-api/mrpclb/src/dp.rs new file mode 100644 index 00000000..b6891829 --- /dev/null +++ b/experimental/mrpc/phoenix-api/mrpclb/src/dp.rs @@ -0,0 +1,39 @@ +//! mRPC data path operations. +use serde::{Deserialize, Serialize}; + +use phoenix_api::rpc::{CallId, MessageErased, RpcId, TransportStatus}; +use phoenix_api::Handle; + +pub type WorkRequestSlot = [u8; 64]; + +pub const RECV_RECLAIM_BS: usize = 4; + +#[repr(C, align(64))] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub enum WorkRequest { + Call(MessageErased), + // this will also deallocate + Reply(MessageErased), + // conn_id and an array of call_id + ReclaimRecvBuf(Handle, [CallId; RECV_RECLAIM_BS]), +} + +pub type CompletionSlot = [u8; 64]; + +// Avoid using too much `Send`/`Recv` in the code. +#[repr(C, align(64))] +#[derive(Debug, Clone)] +pub enum Completion { + Incoming(MessageErased), + Outgoing(RpcId, TransportStatus), + // (conn_id, status) + RecvError(Handle, TransportStatus), +} + +mod sa { + use super::*; + use static_assertions::const_assert; + use std::mem::size_of; + const_assert!(size_of::() <= size_of::()); + const_assert!(size_of::() <= size_of::()); +} diff --git a/experimental/mrpc/phoenix-api/mrpclb/src/lib.rs b/experimental/mrpc/phoenix-api/mrpclb/src/lib.rs new file mode 100644 index 00000000..d35887fa --- /dev/null +++ b/experimental/mrpc/phoenix-api/mrpclb/src/lib.rs @@ -0,0 +1,3 @@ +pub mod cmd; +pub mod control_plane; +pub mod dp; diff --git a/experimental/mrpc/plugin/load_balancer/Cargo.toml b/experimental/mrpc/plugin/load_balancer/Cargo.toml new file mode 100644 index 00000000..06e493e8 --- /dev/null +++ b/experimental/mrpc/plugin/load_balancer/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "phoenix-load-balancer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["rlib"] + +[dependencies] +phoenix-api-mrpc.workspace = true +phoenix-api-load-balancer.workspace = true +phoenix-mrpc.workspace = true +mrpc-marshal.workspace = true + +phoenix-api = { workspace = true, features = ["mrpc", "transport"] } +ipc.workspace = true +phoenix_common.workspace = true +transport-tcp.workspace = true +phoenix-salloc.workspace = true +utils.workspace = true + +fnv.workspace = true +anyhow.workspace = true +tokio = { workspace = true, features = ["sync"] } +thiserror.workspace = true +nix.workspace = true +futures.workspace = true +dashmap.workspace = true +spin.workspace = true +libloading.workspace = true +serde = { workspace = true, features = ["derive"] } +toml = { workspace = true, features = ["preserve_order"] } +fastrand.workspace = true +bitvec.workspace = true +bincode.workspace = true +socket2.workspace = true +slab.workspace = true diff --git a/experimental/mrpc/plugin/load_balancer/src/engine.rs b/experimental/mrpc/plugin/load_balancer/src/engine.rs new file mode 100644 index 00000000..8a8ce725 --- /dev/null +++ b/experimental/mrpc/plugin/load_balancer/src/engine.rs @@ -0,0 +1,428 @@ +use std::cell::RefCell; +use std::collections::VecDeque; +use std::mem; +use std::os::unix::prelude::{AsRawFd, RawFd}; +use std::pin::Pin; +use std::ptr; +use std::time::Duration; + +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap; +use futures::future::BoxFuture; +use slab::Slab; + +use mrpc_marshal::{ExcavateContext, SgE, SgList}; +use phoenix_api::buf::Range; +use phoenix_api::engine::SchedulingMode; +use phoenix_api::net::{MappedAddrStatus, WcOpcode, WcStatus}; +use phoenix_api::rpc::{CallId, MessageMeta, RpcId, StatusCode, TransportStatus}; +use phoenix_api::transport::tcp::dp::Completion; +use phoenix_api::{AsHandle, Handle}; +use phoenix_api_load_balancer::control_plane; +use phoenix_api_mrpc::cmd::{ConnectResponse, ReadHeapRegion}; +use phoenix_mrpc::unpack::UnpackFromSgE; +use phoenix_salloc::state::State as SallocState; +use transport_tcp::ops::Ops; +use transport_tcp::ApiError; + +use phoenix_common::engine::datapath::message::{ + EngineRxMessage, EngineTxMessage, RpcMessageRx, RpcMessageTx, +}; +use phoenix_common::engine::datapath::meta_pool::{MetaBuffer, MetaBufferPtr}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::{ModuleCollection, Version}; +use phoenix_common::resource::Error as ResourceError; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::get_ops; + +use super::{ControlPathError, DatapathError}; + +thread_local! { + /// To emulate a thread local storage (TLS). This should be called engine-local-storage (ELS). + pub(crate) static ELS: RefCell> = RefCell::new(None); +} + +pub(crate) struct TlStorage { + pub(crate) ops: Ops, +} + +pub(crate) struct LoadBalancerEngine { + pub(crate) node: DataPathNode, + pub(crate) p2v: FnvHashMap, + pub(crate) v2p: FnvHashMap>, + pub(crate) buffer: FnvHashMap, + pub(crate) cmd_rx_upstream: + tokio::sync::mpsc::UnboundedReceiver, + pub(crate) cmd_tx_upstream: + tokio::sync::mpsc::UnboundedSender, + pub(crate) cmd_rx_downstream: + tokio::sync::mpsc::UnboundedReceiver, + pub(crate) cmd_tx_downstream: + tokio::sync::mpsc::UnboundedSender, + pub(crate) _mode: SchedulingMode, + pub(crate) indicator: Indicator, + // pub(crate) start: std::time::Instant, + pub(crate) rpc_ctx: Slab, +} + +impl_vertex_for_engine!(LoadBalancerEngine, node); + +impl Decompose for LoadBalancerEngine { + #[inline] + fn flush(&mut self) -> Result { + // each call to `check_input_queue()` receives at most one message + let mut work = 0; + while !self.tx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + // NOTE(wyj): if command/data queue types need to be upgraded + // then the channels must be recreated + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(14); + log::debug!("dumping LoadBalancerEngine states..."); + + let node = unsafe { + collections.insert("mode".to_string(), Box::new(ptr::read(&engine._mode))); + collections.insert( + "cmd_tx_upstream".to_string(), + Box::new(ptr::read(&engine.cmd_tx_upstream)), + ); + collections.insert( + "cmd_rx_upstream".to_string(), + Box::new(ptr::read(&engine.cmd_rx_upstream)), + ); + collections.insert( + "cmd_tx_downstream".to_string(), + Box::new(ptr::read(&engine.cmd_tx_downstream)), + ); + collections.insert( + "cmd_rx_downstream".to_string(), + Box::new(ptr::read(&engine.cmd_rx_downstream)), + ); + collections.insert("rpc_ctx".to_string(), Box::new(ptr::read(&engine.rpc_ctx))); + // don't call the drop function + ptr::read(&engine.node) + }; + + mem::forget(engine); + + (collections, node) + } +} + +impl LoadBalancerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + node: DataPathNode, + _plugged: &ModuleCollection, + _prev_version: Version, + ) -> Result { + log::debug!("restoring LoadBalancerEngine states..."); + + let mode = *local + .remove("mode") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let p2v = *local + .remove("p2v") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let v2p = *local + .remove("v2p") + .unwrap() + .downcast::>>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let buffer = *local + .remove("buffer") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let cmd_tx_upstream = *local + .remove("cmd_tx_upstream") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let cmd_rx_upstream = *local + .remove("cmd_rx_upstream") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let cmd_tx_downstream = *local + .remove("cmd_tx_downstream") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let cmd_rx_downstream = *local + .remove("cmd_rx_downstream") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let rpc_ctx = *local + .remove("rpc_ctx") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let engine = LoadBalancerEngine { + p2v, + v2p, + buffer, + cmd_tx_upstream, + cmd_rx_upstream, + cmd_tx_downstream, + cmd_rx_downstream, + node, + _mode: mode, + indicator: Default::default(), // start: std::time::Instant::now(), + rpc_ctx, + }; + Ok(engine) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for LoadBalancerEngine { + fn description(self: Pin<&Self>) -> String { + format!("LoadBalancerEngine, user",) + } + + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request( + &mut self, + request: Vec, + _cred: std::os::unix::ucred::UCred, + ) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + // TODO: send result to userland + match request { + control_plane::Request::ListConnection => { + let table = get_ops().state.sock_table.borrow(); + let mut connections = Vec::with_capacity(table.len()); + for (handle, (sock, _status)) in table.iter() { + let conn = control_plane::Connection { + sock: *handle, + local: sock.local_addr()?, + peer: sock.peer_addr()?, + }; + connections.push(conn); + } + + for conn in connections { + log::info!( + "LoadBalancer connection, Socket={:?}, local_addr={:?}, peer_addr={:?}", + conn.sock, + conn.local, + conn.peer + ); + } + } + } + + Ok(()) + } +} + +impl Drop for LoadBalancerEngine { + fn drop(&mut self) { + let this = Pin::new(self); + let desc = this.as_ref().description(); + log::warn!("{} is being dropped", desc); + } +} + +impl LoadBalancerEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + // let mut timer = utils::timer::Timer::new(); + + let mut work = 0; + // let mut nums = Vec::new(); + + match self.check_input_queue()? { + Progress(n) => { + work += n; + // nums.push(n) + } + Status::Disconnected => return Ok(()), + } + // timer.tick(); + + match self.check_input_cmd_queue()? { + Progress(n) => { + work += n; + // nums.push(n) + } + Status::Disconnected => return Ok(()), + } + + match self.check_input_comp_queue()? { + Progress(n) => { + work += n; + // nums.push(n) + } + Status::Disconnected => return Ok(()), + } + + self.indicator.set_nwork(work); + + // timer.tick(); + // if work > 0 { + // log::info!("LoadBalancer mainloop: {:?} {}", nums, timer); + // } + future::yield_now().await; + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum RpcStrategy { + /// The entire message is encapuslated into one message, transmitted with one send/recv + Fused, + /// The message is marshaled into an SgList, and transmitted with multiple send/recv operations. + Standard, +} + +impl LoadBalancerEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let conn_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id: CallId = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.call_id; + + if conn_id == Handle::MASTER { + self.buffer.insert(call_id, 0); + let rconns = self + .v2p + .get(&conn_id) + .ok_or(DatapathError::Resource(ResourceError::NotFound))?; + let new_conn_id = rconns[call_id.0 as usize % rconns.len()]; + + unsafe { + (*msg.meta_buf_ptr.as_meta_ptr()).conn_id = new_conn_id; + }; + } + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + match m { + EngineRxMessage::Ack(rpc_id, status) => { + let call_id = rpc_id.1; + if let Some(_) = self.buffer.get(&call_id) { + let new_rpc_id = RpcId(Handle::MASTER, call_id); + self.buffer.remove(&call_id); + self.rx_outputs()[0].send(EngineRxMessage::Ack(new_rpc_id, status))?; + } else { + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + } + _ => { + self.rx_outputs()[0].send(m)?; + } + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } + + fn check_input_cmd_queue(&mut self) -> Result { + use phoenix_api_mrpc::cmd::{Command, Completion, CompletionKind}; + + use tokio::sync::mpsc::error::TryRecvError; + match self.cmd_rx_upstream.try_recv() { + Ok(req) => { + match req { + Command::MultiConnect(handles) => { + let vid = Handle::MASTER; + log::info!("build conn mapping: {:?} -> {:?}", handles, vid); + self.v2p.insert(vid, handles.clone()); + for handle in handles { + self.p2v.insert(handle, vid); + } + let comp = CompletionKind::MultiConnect(vid); + self.cmd_tx_upstream.send(Completion(Ok(comp)))?; + } + _ => { + self.cmd_tx_downstream.send(req)?; + } + } + Ok(Status::Progress(1)) + } + Err(TryRecvError::Empty) => Ok(Status::Progress(0)), + Err(TryRecvError::Disconnected) => Ok(Status::Disconnected), + } + } + fn check_input_comp_queue(&mut self) -> Result { + use phoenix_api_mrpc::cmd::{Completion, CompletionKind}; + use tokio::sync::mpsc::error::TryRecvError; + + match self.cmd_rx_downstream.try_recv() { + Ok(Completion(comp)) => { + self.cmd_tx_upstream.send(Completion(comp))?; + Ok(Status::Progress(1)) + } + Err(TryRecvError::Empty) => Ok(Status::Progress(0)), + Err(TryRecvError::Disconnected) => Ok(Status::Disconnected), + } + } +} diff --git a/experimental/mrpc/plugin/load_balancer/src/lib.rs b/experimental/mrpc/plugin/load_balancer/src/lib.rs new file mode 100644 index 00000000..ae797b4f --- /dev/null +++ b/experimental/mrpc/plugin/load_balancer/src/lib.rs @@ -0,0 +1,93 @@ +#![feature(ptr_internals)] +#![feature(strict_provenance)] +#![feature(local_key_cell_methods)] +#![feature(peer_credentials_unix_socket)] + +use std::alloc::LayoutError; + +use phoenix_common::engine::datapath::EngineRxMessage; +use phoenix_common::engine::datapath::EngineTxMessage; +use phoenix_salloc::region; +use phoenix_salloc::ControlPathError as SallocError; +use thiserror::Error; +use transport_tcp::{ops, ApiError, TransportError}; + +use phoenix_common::resource::Error as ResourceError; +pub use phoenix_common::{InitFnResult, PhoenixModule}; + +pub mod module; + +pub(crate) mod engine; + +#[inline] +fn get_ops() -> &'static ops::Ops { + use crate::engine::ELS; + ELS.with(|els| &els.borrow().as_ref().unwrap().ops) +} + +#[derive(Error, Debug)] +#[error("load-balancer control path error")] +pub(crate) enum ControlPathError { + // Below are errors that return to the user. + #[error("Controlpath API error in socket: {0}")] + ApiError(#[from] ApiError), + #[error("TCP transport error: {0}")] + TransportError(#[from] TransportError), + #[error("Resource error: {0}")] + Resource(#[from] ResourceError), + #[error("Salloc error: {0}")] + Salloc(#[from] SallocError), + #[error("Invalid layout: {0}")] + Layout(#[from] LayoutError), + #[error("SharedRegion allocate error: {0}")] + SharedRegion(#[from] region::Error), + #[error("{0}")] + InsertAddrMap(#[from] mrpc_marshal::AddressExists), + + // Below are errors that does not return to the user. + #[error("Send command error")] + SendCommand, + #[error("Service error: {0}")] + Service(#[from] ipc::Error), + #[error("Loading dispatch library: {0}")] + LibLoading(#[from] libloading::Error), +} + +impl From for phoenix_api::Error { + fn from(other: ControlPathError) -> Self { + phoenix_api::Error::Generic(other.to_string()) + } +} + +use tokio::sync::mpsc::error::SendError; +impl From> for ControlPathError { + fn from(_other: SendError) -> Self { + Self::SendCommand + } +} + +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, + #[error("Resource error: {0}")] + Resource(#[from] ResourceError), + #[error("Tx queue send error: {0}")] + Tx(#[from] phoenix_common::engine::datapath::SendError), + #[error("Rx queue send error: {0}")] + Rx(#[from] phoenix_common::engine::datapath::SendError), +} + +use crate::module::LoadBalancerModule; + +#[no_mangle] +pub fn init_module(_config_string: Option<&str>) -> InitFnResult> { + let module = LoadBalancerModule::new(); + Ok(Box::new(module)) +} diff --git a/experimental/mrpc/plugin/load_balancer/src/module.rs b/experimental/mrpc/plugin/load_balancer/src/module.rs new file mode 100644 index 00000000..b1d86839 --- /dev/null +++ b/experimental/mrpc/plugin/load_balancer/src/module.rs @@ -0,0 +1,235 @@ +use anyhow::{anyhow, bail, Result}; +use std::collections::{HashMap, VecDeque}; +use std::sync::Arc; + +use nix::unistd::Pid; + +use phoenix_api::engine::SchedulingMode; +use phoenix_api_mrpc::cmd; + +use phoenix_salloc::module::SallocModule; +use phoenix_salloc::region::AddressMediator; +use phoenix_salloc::state::{Shared as SallocShared, State as SallocState}; +use transport_tcp::module::TcpTransportModule; +use transport_tcp::ops::Ops; + +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EnginePair, EngineType}; +use phoenix_common::log; +use phoenix_common::module::{ + ModuleCollection, ModuleDowncast, NewEngineRequest, PhoenixModule, ServiceInfo, Version, +}; +use phoenix_common::state_mgr::SharedStateManager; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use crate::engine::{LoadBalancerEngine, TlStorage}; + +pub(crate) struct LoadBalancerEngineBuilder { + _client_pid: Pid, + mode: SchedulingMode, + cmd_rx_upstream: tokio::sync::mpsc::UnboundedReceiver, + cmd_tx_upstream: tokio::sync::mpsc::UnboundedSender, + cmd_rx_downstream: tokio::sync::mpsc::UnboundedReceiver, + cmd_tx_downstream: tokio::sync::mpsc::UnboundedSender, + node: DataPathNode, +} + +impl LoadBalancerEngineBuilder { + #[allow(clippy::too_many_arguments)] + fn new( + client_pid: Pid, + mode: SchedulingMode, + cmd_tx_upstream: tokio::sync::mpsc::UnboundedSender, + cmd_rx_upstream: tokio::sync::mpsc::UnboundedReceiver, + cmd_tx_downstream: tokio::sync::mpsc::UnboundedSender, + cmd_rx_downstream: tokio::sync::mpsc::UnboundedReceiver, + + node: DataPathNode, + ) -> Self { + LoadBalancerEngineBuilder { + _client_pid: client_pid, + mode, + cmd_tx_upstream, + cmd_rx_upstream, + cmd_tx_downstream, + cmd_rx_downstream, + node, + } + } + + fn build(self) -> Result { + Ok(LoadBalancerEngine { + p2v: Default::default(), + v2p: Default::default(), + buffer: Default::default(), + cmd_tx_upstream: self.cmd_tx_upstream, + cmd_rx_upstream: self.cmd_rx_upstream, + cmd_tx_downstream: self.cmd_tx_downstream, + cmd_rx_downstream: self.cmd_rx_downstream, + node: self.node, + _mode: self.mode, + indicator: Default::default(), + // start: std::time::Instant::now(), + rpc_ctx: Default::default(), + }) + } +} + +pub struct LoadBalancerModule {} + +impl LoadBalancerModule { + pub const LOAD_BALANCER_ENGINE: EngineType = EngineType("LoadBalancerEngine"); + pub const ENGINES: &'static [EngineType] = &[LoadBalancerModule::LOAD_BALANCER_ENGINE]; + pub const DEPENDENCIES: &'static [EnginePair] = &[]; +} + +impl Default for LoadBalancerModule { + fn default() -> Self { + Self::new() + } +} + +impl LoadBalancerModule { + pub fn new() -> Self { + LoadBalancerModule {} + } +} + +impl PhoenixModule for LoadBalancerModule { + fn service(&self) -> Option { + None + } + + fn engines(&self) -> &[EngineType] { + Self::ENGINES + } + + fn dependencies(&self) -> &[EnginePair] { + Self::DEPENDENCIES + } + + fn check_compatibility(&self, _prev: Option<&Version>, _curr: &HashMap<&str, Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let module = *self; + let mut collections = ResourceCollection::new(); + collections + } + + fn migrate(&mut self, prev_module: Box) { + // NOTE(wyj): we may better call decompose here + let prev_concrete = unsafe { *prev_module.downcast_unchecked::() }; + } + + fn create_engine( + &mut self, + ty: EngineType, + request: NewEngineRequest, + shared: &mut SharedStorage, + _global: &mut ResourceCollection, + node: DataPathNode, + plugged: &ModuleCollection, + ) -> Result>> { + log::info!("create_engine: mrpc lb engine"); + match ty { + Self::LOAD_BALANCER_ENGINE => { + if let NewEngineRequest::Auxiliary { + pid: client_pid, + mode, + config_string: _, + } = request + { + let (cmd_sender, cmd_receiver) = tokio::sync::mpsc::unbounded_channel(); + + shared + .command_path + .put_sender(Self::LOAD_BALANCER_ENGINE, cmd_sender)?; + + let (comp_sender, comp_receiver) = tokio::sync::mpsc::unbounded_channel(); + + shared + .command_path + .put_receiver(Self::LOAD_BALANCER_ENGINE, comp_receiver)?; + + let tx_down = shared + .command_path + .get_sender(&EngineType("TcpRpcAdapterEngine"))?; + + let rx_down = shared + .command_path + .get_receiver(&EngineType("TcpRpcAdapterEngine"))?; + + let engine = self.create_load_balancer_engine( + mode, + client_pid, + comp_sender, + cmd_receiver, + tx_down, + rx_down, + node, + )?; + Ok(Some(Box::new(engine))) + } else { + bail!("invalid request type") + } + } + _ => bail!("invalid engine type {:?}", ty), + } + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + shared: &mut SharedStorage, + global: &mut ResourceCollection, + node: DataPathNode, + plugged: &ModuleCollection, + prev_version: Version, + ) -> Result> { + match ty { + Self::LOAD_BALANCER_ENGINE => { + let engine = LoadBalancerEngine::restore( + local, + shared, + global, + node, + plugged, + prev_version, + )?; + Ok(Box::new(engine)) + } + _ => bail!("invalid engine type {:?}", ty), + } + } +} + +impl LoadBalancerModule { + #[allow(clippy::too_many_arguments)] + fn create_load_balancer_engine( + &mut self, + mode: SchedulingMode, + client_pid: Pid, + cmd_tx_upstream: tokio::sync::mpsc::UnboundedSender, + cmd_rx_upstream: tokio::sync::mpsc::UnboundedReceiver, + cmd_tx_downstream: tokio::sync::mpsc::UnboundedSender, + cmd_rx_downstream: tokio::sync::mpsc::UnboundedReceiver, + node: DataPathNode, + ) -> Result { + // Acceptor engine should already been created at this momen + + let builder = LoadBalancerEngineBuilder::new( + client_pid, + mode, + cmd_tx_upstream, + cmd_rx_upstream, + cmd_tx_downstream, + cmd_rx_downstream, + node, + ); + let engine = builder.build()?; + Ok(engine) + } +} diff --git a/experimental/mrpc/plugin/mrpc/src/engine.rs b/experimental/mrpc/plugin/mrpc/src/engine.rs index 655c1841..f8a7bb13 100644 --- a/experimental/mrpc/plugin/mrpc/src/engine.rs +++ b/experimental/mrpc/plugin/mrpc/src/engine.rs @@ -337,6 +337,9 @@ impl MrpcEngine { .unwrap(); Ok(None) } + Command::MultiConnect(_) => { + panic!("MultiConnect is only used in mrpclb") + } Command::UpdateProtosInner(_) => { panic!("UpdateProtosInner is only used in backend") } diff --git a/experimental/mrpc/plugin/mrpc/src/module.rs b/experimental/mrpc/plugin/mrpc/src/module.rs index 892f9500..9a59df2c 100644 --- a/experimental/mrpc/plugin/mrpc/src/module.rs +++ b/experimental/mrpc/plugin/mrpc/src/module.rs @@ -212,6 +212,7 @@ impl PhoenixModule for MrpcModule { node: DataPathNode, _plugged: &ModuleCollection, ) -> PhoenixResult>> { + log::info!("create_engine mrpc module!"); if ty != MrpcModule::MRPC_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -248,6 +249,7 @@ impl PhoenixModule for MrpcModule { transport: self.config.transport, nic_index: self.config.nic_index, core_id: None, + module_config: None, } }; log::debug!("mRPC service setting: {:?}", setting); @@ -262,7 +264,7 @@ impl PhoenixModule for MrpcModule { // as the RpcAdapterEngine is built first // according to the topological order let cmd_tx = shared.command_path.get_sender(&engine_type)?; - let cmd_rx = shared.command_path.get_receiver(&MrpcModule::MRPC_ENGINE)?; + let cmd_rx = shared.command_path.get_receiver(&engine_type)?; let builder = MrpcEngineBuilder::new( customer, diff --git a/experimental/mrpc/plugin/mrpclb/Cargo.toml b/experimental/mrpc/plugin/mrpclb/Cargo.toml new file mode 100644 index 00000000..19bd576d --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "phoenix-mrpclb" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["rlib"] + +[dependencies] +phoenix-api-mrpc.workspace = true +mrpc-marshal.workspace = true + +phoenix-api = { workspace = true, features = ["mrpc"] } +ipc.workspace = true +phoenix_common.workspace = true +prost-build = { workspace = true, features = ["mrpc-backend"] } +utils.workspace = true + +tokio = { workspace = true, features = ["sync"] } +anyhow.workspace = true +lazy_static.workspace = true +fnv.workspace = true +uuid.workspace = true +futures.workspace = true +thiserror.workspace = true +itertools.workspace = true +crc32fast.workspace = true +fastrand.workspace = true +syn.workspace = true +quote.workspace = true +proc-macro2.workspace = true +md5.workspace = true +prettyplease.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +static_assertions.workspace = true diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/cache.rs b/experimental/mrpc/plugin/mrpclb/src/builder/cache.rs new file mode 100644 index 00000000..30a02cf4 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/cache.rs @@ -0,0 +1,61 @@ +use std::path::Path; + +pub fn check_cache>( + protos: &[String], + // dir to backend build cache + cache_dir: P, + // directory name where the proto files are stored + // should be a directory name/path + // relative to `cache_dir` + proto_dir: &str, +) -> std::io::Result<(String, bool)> { + let mut checksum_ctx = md5::Context::new(); + for proto in protos.iter() { + checksum_ctx.consume(proto.as_bytes()); + } + let app_identifier = format!("{:0x}", checksum_ctx.compute()); + + // protos are stored in cache_dir/proto_dir + let cached_proto_dir = cache_dir.as_ref().join(&app_identifier).join(proto_dir); + if !cached_proto_dir.is_dir() { + return Ok((app_identifier, false)); + } + for (idx, proto) in protos.iter().enumerate() { + let filename = cached_proto_dir.join(format! {"{}.proto", idx}); + let proto_from_file = std::fs::read_to_string(filename)?; + // check if proto file matches + if !proto.eq(&proto_from_file) { + return Ok((app_identifier, false)); + } + } + + Ok((app_identifier, true)) +} + +pub fn write_protos_to_cache>( + identifier: &str, + protos: &[String], + // dir to backend build cache + cache_dir: P, + // directory name where the proto files are stored + // should be a directory name/path + // relative to `cache_dir` + proto_dir: &str, +) -> std::io::Result<()> { + let app_folder = cache_dir.as_ref().join(identifier); + if !app_folder.is_dir() { + std::fs::create_dir(&app_folder)?; + } + + let proto_dir = app_folder.join(proto_dir); + if !proto_dir.is_dir() { + std::fs::create_dir(&proto_dir)?; + } + + for (idx, proto) in protos.iter().enumerate() { + let filename = proto_dir.join(format!("{}.proto", idx)); + std::fs::write(filename, proto)?; + } + + Ok(()) +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/compiler/code_generator.rs b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/code_generator.rs new file mode 100644 index 00000000..bbe70d71 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/code_generator.rs @@ -0,0 +1,120 @@ +use std::collections::HashMap; +use std::path::PathBuf; + +use proc_macro2::TokenStream; +use quote::quote; +use syn::Result; + +use super::{MethodIdentifier, RpcMethodInfo}; + +pub fn generate_marshal(method_id: &MethodIdentifier, ty: &str) -> Result { + let func_id = method_id.1; + let rust_ty = syn::parse_str::(&format!("codegen::{}", ty))?; + let marshal = quote! { + #func_id => { + let ptr_backend = addr_backend as *mut #rust_ty; + assert_eq!(ptr_backend.align_offset(std::mem::align_of::<#rust_ty>()), 0); + let msg_ref = unsafe { &*ptr_backend }; + msg_ref.marshal() + }, + }; + Ok(marshal) +} + +pub fn generate_unmarshal(method_id: &MethodIdentifier, ty: &str) -> Result { + let func_id = method_id.1; + let rust_ty = syn::parse_str::(&format!("codegen::{}", ty))?; + let unmarshal = quote! { + # func_id => { + let msg = #rust_ty::unmarshal(ctx)?; + let (ptr_app, ptr_backend) = msg.to_raw_parts(); + (ptr_app.addr().get(), ptr_backend.addr().get()) + }, + }; + Ok(unmarshal) +} + +pub fn generate( + include_file: PathBuf, + method_type_mapping: &HashMap, +) -> Result { + let include_file = include_file.to_str().unwrap(); + + let requests_marshal = method_type_mapping + .iter() + .map(|(id, info)| generate_marshal(id, &info.input_type)) + .collect::>>()?; + + let requests_unmarshal = method_type_mapping + .iter() + .map(|(id, info)| generate_unmarshal(id, &info.input_type)) + .collect::>>()?; + + let responses_marshal = method_type_mapping + .iter() + .map(|(id, info)| generate_marshal(id, &info.output_type)) + .collect::>>()?; + + let response_unmarshal = method_type_mapping + .iter() + .map(|(id, info)| generate_unmarshal(id, &info.output_type)) + .collect::>>()?; + + let dispatch = quote! { + #![feature(strict_provenance)] + + use phoenix_api::rpc::{MessageMeta, RpcMsgType}; + use mrpc_marshal::{SgList, ExcavateContext, RpcMessage}; + use mrpc_marshal::{MarshalError, UnmarshalError, AddressMap}; + + mod codegen { + include!(#include_file); + } + + #[no_mangle] + pub extern "Rust" fn marshal( + meta: &MessageMeta, + addr_backend: usize, + ) -> Result { + match meta.msg_type { + RpcMsgType::Request => { + match meta.func_id { + #(#requests_marshal)* + _ => panic!("unknown func_id: {}, meta: {:?}", meta.func_id, meta), + } + }, + RpcMsgType::Response => { + match meta.func_id { + #(#responses_marshal)* + _ => panic!("unknown func_id: {}, meta: {:?}", meta.func_id, meta), + } + } + } + } + + #[no_mangle] + pub unsafe extern "Rust" fn unmarshal( + meta: &MessageMeta, + ctx: &mut ExcavateContext, + ) -> Result<(usize, usize), UnmarshalError> { + let addr_shm = match meta.msg_type { + RpcMsgType::Request => { + match meta.func_id { + #(#requests_unmarshal)* + _ => panic!("unknown func_id: {}, meta: {:?}", meta.func_id, meta), + } + }, + RpcMsgType::Response => { + match meta.func_id { + #(#response_unmarshal)* + _ => panic!("unknown func_id: {}, meta: {:?}", meta.func_id, meta), + } + } + }; + + Ok(addr_shm) + } + }; + + Ok(dispatch) +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/compiler/mod.rs b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/mod.rs new file mode 100644 index 00000000..ca4a41c6 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/mod.rs @@ -0,0 +1,101 @@ +use std::collections::HashMap; +use std::fs; +use std::path::PathBuf; +use std::process::Command; + +use thiserror::Error; + +use super::{MethodIdentifier, RpcMethodInfo}; + +mod code_generator; + +const MRPC_DERIVE: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../mrpc-derive"); +const MRPC_MARSHAL: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../mrpc-marshal"); +const SHM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../../src/shm"); +const PHOENIX_API: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../../src/phoenix-api"); +// Make sure the compiler for plugins is the same as the compiler for the backend. +const TOOLCHAIN: &str = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../../rust-toolchain" +)); + +#[derive(Error, Debug)] +pub enum Error { + #[error("IO Error: {0}")] + IO(#[from] std::io::Error), + #[error("Syn Parse Error: {0}")] + SynParse(#[from] syn::Error), + #[error("Cargo build failed")] + Cargo, +} + +#[cfg(target_os = "macos")] +pub const DYLIB_FILENAME: &str = "libdispatch.dylib"; +#[cfg(target_os = "linux")] +pub const DYLIB_FILENAME: &str = "libdispatch.so"; + +pub struct Builder { + /// directory to emit the dispatch dylib crate + pub(crate) emit_crate_dir: PathBuf, + /// the directory to the generated Rust code produeced by prost-build + /// default to "prost" in emit_cache_dir's parent directory + pub(crate) prost_out_dir: Option, + /// the name of the include file generated by prost-build + /// default to "_include.rs" + pub(crate) include_filename: Option, + pub(crate) method_type_mapping: HashMap, +} + +impl Builder { + pub fn compile(&self) -> Result { + if self.emit_crate_dir.is_dir() { + fs::remove_dir_all(&self.emit_crate_dir).unwrap(); + } else if self.emit_crate_dir.is_file() { + fs::remove_file(&self.emit_crate_dir).unwrap(); + } + fs::create_dir(&self.emit_crate_dir).unwrap(); + fs::create_dir(&self.emit_crate_dir.join("src")).unwrap(); + + let prost_out_dir = self + .prost_out_dir + .to_owned() + .unwrap_or_else(|| self.emit_crate_dir.parent().unwrap().join("prost")); + let prost_include_file = prost_out_dir + .join(self.include_filename.as_deref().unwrap_or("_include.rs")) + .canonicalize() + .unwrap(); + + let tokens = code_generator::generate(prost_include_file, &self.method_type_mapping)?; + + let ast: syn::File = syn::parse2(tokens)?; + let code = prettyplease::unparse(&ast); + fs::write(self.emit_crate_dir.join("src/lib.rs"), &code).unwrap(); + + let manifest = format!( + include_str!("template/Cargo.toml"), + mrpc_derive = MRPC_DERIVE, + mrpc_marshal = MRPC_MARSHAL, + shm = SHM, + phoenix_api = PHOENIX_API, + ); + fs::write(self.emit_crate_dir.join("Cargo.toml"), manifest).unwrap(); + + fs::write(self.emit_crate_dir.join("rust-toolchain"), TOOLCHAIN).unwrap(); + + let mut cmd = Command::new("cargo"); + cmd.arg("build").arg("--release"); + cmd.current_dir(&self.emit_crate_dir); + + let status = cmd.status()?; + if !status.success() { + // failed to run cargo build + return Err(Error::Cargo); + } + + let dylib_path = self + .emit_crate_dir + .join(format!("target/release/{}", DYLIB_FILENAME)); + + Ok(dylib_path) + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/compiler/template/Cargo.toml b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/template/Cargo.toml new file mode 100644 index 00000000..9954dae4 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/compiler/template/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "dispatch" +version = "1.0.0" +edition = "2021" + +[lib] +crate-type = ["dylib"] + +[dependencies] +mrpc-derive = {{ path = "{mrpc_derive}" }} +mrpc-marshal = {{ path = "{mrpc_marshal}" }} +shm = {{ path = "{shm}" }} +phoenix-api = {{ path = "{phoenix_api}", features = ["mrpc"] }} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/mod.rs b/experimental/mrpc/plugin/mrpclb/src/builder/mod.rs new file mode 100644 index 00000000..fc2e87c9 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/mod.rs @@ -0,0 +1,173 @@ +use std::path::PathBuf; +use std::process::Command; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +pub mod cache; +pub mod compiler; +pub mod prost; + +const PROTO_DIR: &str = "proto"; +const PROST_DIR: &str = "prost"; +const LIBRARY_DIR: &str = "marshal"; +const PROST_INCLUDE_FILE: &str = "_include.rs"; + +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] +pub struct MethodIdentifier(u32, u32); + +impl Serialize for MethodIdentifier { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&format!("{}_{}", self.0, self.1)) + } +} + +struct MethodIdentifierVisitor; + +impl<'de> serde::de::Visitor<'de> for MethodIdentifierVisitor { + type Value = MethodIdentifier; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a underscore seperate pair of service_id and func_id)") + } + + fn visit_str(self, s: &str) -> Result + where + E: serde::de::Error, + { + let mut iter = s.split('_'); + let service_id = if let Some(service_id) = iter.next() { + if let Ok(id) = u32::from_str(service_id) { + id + } else { + return Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(s), + &self, + )); + } + } else { + return Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(s), + &self, + )); + }; + + let func_id = if let Some(func_id) = iter.next() { + if let Ok(id) = u32::from_str(func_id) { + id + } else { + return Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(s), + &self, + )); + } + } else { + return Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(s), + &self, + )); + }; + + let method_id = MethodIdentifier(service_id, func_id); + Ok(method_id) + } +} + +impl<'de> Deserialize<'de> for MethodIdentifier { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(MethodIdentifierVisitor) + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RpcMethodInfo { + pub service_id: u32, + pub func_id: u32, + // fully qualified path for the method's input rust type + // for extern path, should start with "::" + // for local path that generated by prost-build, + // should start with the package name, e.g., `foo::bar::HelloRequest` + // instead of starting with "::" qualifier + pub input_type: String, + // output type's path + pub output_type: String, +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("IO Error: {0}")] + IO(#[from] std::io::Error), + #[error("prost-build Error: {0}")] + ProstBuild(#[from] prost::Error), + #[error("Marshal Library Compile Error: {0}")] + LibraryCompile(#[from] compiler::Error), +} + +pub fn build_serializer_lib(protos: Vec, cache_dir: PathBuf) -> Result { + // Create cache dir if it does not exists + std::fs::create_dir_all(cache_dir.as_path())?; + let (identifier, cached) = cache::check_cache(&protos, &cache_dir, PROTO_DIR)?; + if !cached { + cache::write_protos_to_cache(&identifier, &protos, &cache_dir, PROTO_DIR)?; + let prost_out_dir = cache_dir.join(&identifier).join(PROST_DIR); + if !prost_out_dir.is_dir() { + std::fs::create_dir(&prost_out_dir)?; + } + + let method_info_out_path = cache_dir.join(&identifier).join("method_info.json"); + + let prost_builder = prost::configure() + .include_file(PROST_INCLUDE_FILE) + .out_dir(&prost_out_dir) + .method_info_out_path(&method_info_out_path); + + let proto_paths = protos + .iter() + .enumerate() + .map(|(idx, _)| { + cache_dir + .join(&identifier) + .join(format!("{}/{}.proto", PROTO_DIR, idx)) + }) + .collect::>(); + let proto_include_path = cache_dir.join(&identifier).join(PROTO_DIR); + // run prost-build to generate Rust structs for messages in proto files + let method_info = prost_builder.compile(proto_paths.as_slice(), &[&proto_include_path])?; + + // generate dispatch library + let emit_crate_dir = cache_dir.join(&identifier).join(LIBRARY_DIR); + let builder = compiler::Builder { + emit_crate_dir, + prost_out_dir: Some(prost_out_dir), + include_filename: Some(PROST_INCLUDE_FILE.to_string()), + method_type_mapping: method_info, + }; + let dylib_path = builder.compile()?; + Ok(dylib_path) + } else { + // Check whether dependencies have changed, + // hence requiring rebuilding the shared library + // TODO(wyj): use a built-in fingerprint mechanism to check changes + // instead of directly using cargo + let emit_crate_dir = cache_dir.join(&identifier).join(LIBRARY_DIR); + let mut cmd = Command::new("cargo"); + cmd.arg("build").arg("--release"); + cmd.current_dir(&emit_crate_dir); + // let status = cmd.stdout(Stdio::null()).stderr(Stdio::null()).status()?; + let status = cmd.status()?; + if !status.success() { + // failed to run cargo build + return Err(Error::LibraryCompile(compiler::Error::Cargo)); + } + let dylib_path = + emit_crate_dir.join(format!("target/release/{}", compiler::DYLIB_FILENAME)); + Ok(dylib_path) + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/prost/mod.rs b/experimental/mrpc/plugin/mrpclb/src/builder/prost/mod.rs new file mode 100644 index 00000000..19f6e5bf --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/prost/mod.rs @@ -0,0 +1,16 @@ +#![allow(clippy::module_inception)] +use thiserror::Error; + +pub mod prost; +pub mod service; + +pub use prost::Builder; +pub use prost::{compile_protos, configure}; + +#[derive(Error, Debug)] +pub enum Error { + #[error("IO Error: {0}")] + IO(#[from] std::io::Error), + #[error("Serde JSON Error: {0}")] + SerdeJSON(#[from] serde_json::Error), +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/prost/prost.rs b/experimental/mrpc/plugin/mrpclb/src/builder/prost/prost.rs new file mode 100644 index 00000000..b50bb933 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/prost/prost.rs @@ -0,0 +1,218 @@ +use std::cell::RefCell; +use std::collections::HashMap; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::rc::Rc; + +use super::super::{MethodIdentifier, RpcMethodInfo}; + +use super::service::ServiceRecorder; +use super::Error; + +pub struct Builder { + file_descriptor_set_path: Option, + type_attributes: Vec<(String, String)>, + field_attributes: Vec<(String, String)>, + compile_well_known_types: bool, + extern_paths: Vec<(String, String)>, + default_package_filename: Option, + protoc_args: Vec, + include_file: Option, + out_dir: Option, + method_info_out_path: Option, +} + +pub fn configure() -> Builder { + Builder { + file_descriptor_set_path: None, + type_attributes: Vec::new(), + field_attributes: Vec::new(), + compile_well_known_types: false, + extern_paths: Vec::new(), + default_package_filename: None, + protoc_args: Vec::new(), + include_file: None, + out_dir: None, + method_info_out_path: None, + } +} + +pub fn compile_protos( + proto: impl AsRef, +) -> Result, Error> { + let proto_path: &Path = proto.as_ref(); + + // directory the main .proto file resides in + let proto_dir = proto_path + .parent() + .expect("proto file should reside in a directory"); + + let method_info = self::configure().compile(&[proto_path], &[proto_dir])?; + + Ok(method_info) +} + +impl Builder { + /// Set the output directory to generate code to. + /// + /// Defaults to the `OUT_DIR` environment variable. + pub fn out_dir(mut self, out_dir: impl AsRef) -> Self { + self.out_dir = Some(out_dir.as_ref().to_path_buf()); + self + } + + /// Configures for prost-build what filename protobufs with no package definition are written to + pub fn default_package_filename(mut self, filename: S) -> Self + where + S: Into, + { + self.default_package_filename = Some(filename.into()); + self + } + + /// Set the output path for the method info (method id to input/output types mapping). + /// + /// If not set, the method info will not be written to file. + pub fn method_info_out_path(mut self, out_path: impl AsRef) -> Self { + self.method_info_out_path = Some(out_path.as_ref().to_path_buf()); + self + } + + /// Generate a file containing the encoded `prost_types::FileDescriptorSet` for protocol buffers + /// modules. This is required for implementing gRPC Server Reflection. + pub fn file_descriptor_set_path(mut self, path: impl AsRef) -> Self { + self.file_descriptor_set_path = Some(path.as_ref().to_path_buf()); + self + } + + /// Add additional attribute to matched messages, enums, and one-offs. + /// + /// Passed directly to `prost_build::Config.type_attribute`. + pub fn type_attribute, A: AsRef>(mut self, path: P, attribute: A) -> Self { + self.type_attributes + .push((path.as_ref().to_string(), attribute.as_ref().to_string())); + self + } + + /// Add additional attribute to matched messages, enums, and one-offs. + /// + /// Passed directly to `prost_build::Config.field_attribute`. + pub fn field_attribute, A: AsRef>(mut self, path: P, attribute: A) -> Self { + self.field_attributes + .push((path.as_ref().to_string(), attribute.as_ref().to_string())); + self + } + + /// Enable or disable directing Prost to compile well-known protobuf types instead + /// of using the already-compiled versions available in the `prost-types` crate. + /// + /// This defaults to `false`. + pub fn compile_well_known_types(mut self, compile_well_known_types: bool) -> Self { + self.compile_well_known_types = compile_well_known_types; + self + } + + /// Declare externally provided Protobuf package or type. + /// + /// Passed directly to `prost_build::Config.extern_path`. + /// Note that both the Protobuf path and the rust package paths should both be fully qualified. + /// i.e. Protobuf paths should start with "." and rust paths should start with "::", + /// and it should not refer to `crate` + pub fn extern_path(mut self, proto_path: impl AsRef, rust_path: impl AsRef) -> Self { + self.extern_paths.push(( + proto_path.as_ref().to_string(), + rust_path.as_ref().to_string(), + )); + self + } + + /// Configure Prost `protoc_args` build arguments. + /// + /// Note: Enabling `--experimental_allow_proto3_optional` requires protobuf >= 3.12. + pub fn protoc_arg>(mut self, arg: A) -> Self { + self.protoc_args.push(arg.as_ref().into()); + self + } + + /// Configures the optional module filename for easy inclusion of all generated Rust files + /// + /// If set, generates a file (inside the `OUT_DIR` or `out_dir()` as appropriate) which contains + /// a set of `pub mod XXX` statements combining to load all Rust files generated. This can allow + /// for a shortcut where multiple related proto files have been compiled together resulting in + /// a semi-complex set of includes. + pub fn include_file(mut self, path: impl AsRef) -> Self { + self.include_file = Some(path.as_ref().to_path_buf()); + self + } + + /// Compile the .proto files and execute code generation. + pub fn compile( + self, + protos: &[impl AsRef], + includes: &[impl AsRef], + ) -> Result, Error> { + self.compile_with_config(prost_build::Config::new(), protos, includes) + } + + /// Configure the optional + + /// Compile the .proto files and execute code generation using a + /// custom `prost_build::Config`. + /// Returns (service_id, func_id) -> method info mapping + pub fn compile_with_config( + self, + mut config: prost_build::Config, + protos: &[impl AsRef], + includes: &[impl AsRef], + ) -> Result, Error> { + let out_dir = if let Some(out_dir) = self.out_dir.as_ref() { + out_dir.clone() + } else { + PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("prost") + }; + + config.out_dir(out_dir); + if let Some(path) = self.file_descriptor_set_path.as_ref() { + config.file_descriptor_set_path(path); + } + for (proto_path, rust_path) in self.extern_paths.iter() { + config.extern_path(proto_path, rust_path); + } + for (prost_path, attr) in self.field_attributes.iter() { + config.field_attribute(prost_path, attr); + } + for (prost_path, attr) in self.type_attributes.iter() { + config.type_attribute(prost_path, attr); + } + if self.compile_well_known_types { + config.compile_well_known_types(); + } + if let Some(path) = self.include_file.as_ref() { + config.include_file(path); + } + + for arg in self.protoc_args.iter() { + config.protoc_arg(arg); + } + + let method_info = Rc::new(RefCell::new(HashMap::new())); + let recorder = ServiceRecorder { + mapping: method_info.clone(), + compile_well_known_types: self.compile_well_known_types, + }; + config.service_generator(Box::new(recorder)); + + config.compile_protos_mrpc_backend(protos, includes)?; + + std::mem::drop(config); + + let method_info = Rc::try_unwrap(method_info).unwrap().into_inner(); + + if let Some(out_method_info_path) = self.method_info_out_path { + let json = serde_json::to_string_pretty(&method_info)?; + std::fs::write(out_method_info_path, json.as_bytes())?; + } + + Ok(method_info) + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/builder/prost/service.rs b/experimental/mrpc/plugin/mrpclb/src/builder/prost/service.rs new file mode 100644 index 00000000..c9d27f6c --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/builder/prost/service.rs @@ -0,0 +1,112 @@ +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +use itertools::Itertools; + +use super::super::{MethodIdentifier, RpcMethodInfo}; + +pub struct ServiceRecorder { + pub mapping: Rc>>, + pub compile_well_known_types: bool, +} + +impl prost_build::ServiceGenerator for ServiceRecorder { + fn generate(&mut self, service: prost_build::Service, _buf: &mut String) { + let mut mapping = self.mapping.borrow_mut(); + let package = &service.package[..]; + let service_path = get_service_path(package, &service); + let service_id = get_mrpc_service_id(&service_path); + for method in service.methods.iter() { + let method_path = get_method_path(package, &service, method); + let func_id = get_mrpc_func_id(&method_path); + let input_type_canonical = resolve_ident( + package, + &method.input_proto_type, + &method.input_type, + self.compile_well_known_types, + ); + let output_type_canonical = resolve_ident( + package, + &method.output_proto_type, + &method.output_type, + self.compile_well_known_types, + ); + let method_info = RpcMethodInfo { + service_id, + func_id, + input_type: input_type_canonical, + output_type: output_type_canonical, + }; + let method_id = MethodIdentifier(service_id, func_id); + mapping.insert(method_id, method_info); + } + } +} + +const NON_PATH_TYPE_ALLOWLIST: &[&str] = &["()"]; + +fn is_google_type(ty: &str) -> bool { + ty.starts_with(".google.protobuf") +} + +fn resolve_ident( + local_path: &str, + proto_type: &str, + rust_type: &str, + compile_well_known_types: bool, +) -> String { + if (is_google_type(proto_type) && !compile_well_known_types) + || rust_type.starts_with("::") + || NON_PATH_TYPE_ALLOWLIST.iter().any(|ty| *ty == rust_type) + { + // fully qualified path or prost-types + rust_type.to_owned() + } else if rust_type.starts_with("crate::") { + panic!("rust_type should not refer to local crate") + } else { + // relative path + let mut local_path = local_path.split('.'); + let mut rust_type_path = rust_type.split("::").peekable(); + while rust_type_path.peek() == Some(&"super") { + rust_type_path.next(); + local_path.next_back(); + } + local_path.chain(rust_type_path).join("::") + } +} + +// Returns a fully qualified path of a service +fn get_service_path(package: &str, service: &prost_build::Service) -> String { + format!( + "{}{}{}", + package, + if package.is_empty() { "" } else { "." }, + service.proto_name, + ) +} + +// Returnsa fully qualified path of a method +fn get_method_path( + package: &str, + service: &prost_build::Service, + method: &prost_build::Method, +) -> String { + format!( + "/{}{}{}/{}", + package, + if package.is_empty() { "" } else { "." }, + service.proto_name, + method.proto_name, + ) +} + +// Calculate SERVICE_ID for mRPC NamedService. +fn get_mrpc_service_id(path: &str) -> u32 { + crc32fast::hash(path.as_bytes()) +} + +// Calculate FUNC_ID for mRPC remote procedures. +fn get_mrpc_func_id(path: &str) -> u32 { + crc32fast::hash(path.as_bytes()) +} diff --git a/experimental/mrpc/plugin/mrpclb/src/config.rs b/experimental/mrpc/plugin/mrpclb/src/config.rs new file mode 100644 index 00000000..58f296db --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/config.rs @@ -0,0 +1,39 @@ +use std::path::PathBuf; + +use phoenix_api_mrpc::control_plane::TransportType; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MrpcLBConfig { + /// Prefix for the control socket + #[serde(default)] + pub prefix: Option, + /// Base name of the control socket + #[serde(default = "default_engine_basename")] + pub engine_basename: String, + /// The directory to store the build cache + #[serde(default = "default_build_cache")] + pub build_cache: PathBuf, + /// Transport to use + pub transport: TransportType, + /// Use NIC 0 by default + #[serde(default)] + pub nic_index: usize, +} + +impl MrpcLBConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} + +fn default_build_cache() -> PathBuf { + // A path relative to MrpcConfig::prefix if it's non-empty or phoenix_prefix. + PathBuf::from("build_cache") +} + +fn default_engine_basename() -> String { + "mrpclb-engine".to_owned() +} diff --git a/experimental/mrpc/plugin/mrpclb/src/engine.rs b/experimental/mrpc/plugin/mrpclb/src/engine.rs new file mode 100644 index 00000000..baf3f8bc --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/engine.rs @@ -0,0 +1,616 @@ +use std::mem; +use std::path::PathBuf; +use std::pin::Pin; + +use anyhow::{anyhow, Result}; +use futures::future::BoxFuture; +use itertools::Itertools; +use std::num::NonZeroU32; + +use phoenix_api::engine::SchedulingMode; +use phoenix_api::rpc::{MessageErased, RpcId, StatusCode}; +use phoenix_api_mrpc::{cmd, control_plane, dp}; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::meta_pool::MetaBufferPool; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{ + future, Decompose, DecomposeResult, Engine, EngineResult, Indicator, Vertex, +}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::module::{ModuleCollection, Version}; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; +use phoenix_common::{log, tracing}; + +use super::builder::build_serializer_lib; +use super::module::CustomerType; +use super::state::State; +use super::{DatapathError, Error}; + +pub struct MrpcLBEngine { + pub(crate) _state: State, + + pub(crate) customer: CustomerType, + pub(crate) cmd_tx: tokio::sync::mpsc::UnboundedSender, + pub(crate) cmd_rx: tokio::sync::mpsc::UnboundedReceiver, + + pub(crate) node: DataPathNode, + + // mRPC private buffer pools + /// Buffer pool for meta and eager message + pub(crate) meta_buf_pool: MetaBufferPool, + + pub(crate) _mode: SchedulingMode, + + pub(crate) dispatch_build_cache: PathBuf, + + pub(crate) transport_type: Option, + + pub(crate) indicator: Indicator, + pub(crate) wr_read_buffer: Vec, +} + +impl_vertex_for_engine!(MrpcLBEngine, node); + +impl Decompose for MrpcLBEngine { + #[inline] + fn flush(&mut self) -> DecomposeResult { + // mRPC engine has a single receiver on data path, + // i.e., rx_inputs()[0] + // each call to `check_input_queue()` processes at most one message + let mut work = 0; + while !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + // NOTE(wyj): if command queue types need to be upgraded + // then the channels must be recreated + // if the DataPathNode is not flushed, + // upgraded engine must properly handle the remaining messages in the queues + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(10); + log::debug!("dumping MrpcLBEngine states..."); + collections.insert("customer".to_string(), Box::new(engine.customer)); + collections.insert("mode".to_string(), Box::new(engine._mode)); + collections.insert("state".to_string(), Box::new(engine._state)); + collections.insert("cmd_tx".to_string(), Box::new(engine.cmd_tx)); + collections.insert("cmd_rx".to_string(), Box::new(engine.cmd_rx)); + collections.insert("meta_buf_pool".to_string(), Box::new(engine.meta_buf_pool)); + collections.insert( + "dispatch_build_cache".to_string(), + Box::new(engine.dispatch_build_cache), + ); + collections.insert( + "transport_type".to_string(), + Box::new(engine.transport_type), + ); + collections.insert( + "wr_read_buffer".to_string(), + Box::new(engine.wr_read_buffer), + ); + (collections, engine.node) + } +} + +impl MrpcLBEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + node: DataPathNode, + _plugged: &ModuleCollection, + _prev_version: Version, + ) -> Result { + log::debug!("restoring MrpcLBEngine states..."); + + let customer = *local + .remove("customer") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let mode = *local + .remove("mode") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let state = *local + .remove("state") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let cmd_tx = *local + .remove("cmd_tx") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let cmd_rx = *local + .remove("cmd_rx") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let meta_buf_pool = *local + .remove("meta_buf_pool") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let dispatch_build_cache = *local + .remove("dispatch_build_cache") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let transport_type = *local + .remove("transport_type") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let wr_read_buffer = *local + .remove("wr_read_buffer") + .unwrap() + .downcast::>() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let engine = MrpcLBEngine { + _state: state, + customer, + cmd_tx, + cmd_rx, + node, + meta_buf_pool, + _mode: mode, + dispatch_build_cache, + transport_type, + indicator: Default::default(), + wr_read_buffer, + }; + Ok(engine) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for MrpcLBEngine { + fn description(self: Pin<&Self>) -> String { + "MrpcEngine, todo show more information".to_string() + } + + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } +} + +impl MrpcLBEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + // let mut timer = utils::timer::Timer::new(); + let mut nwork = 0; + + // no work 80ns + // has work: <1us for a batch of 30 + loop { + // no work: 40ns + if let Progress(n) = self.check_customer()? { + nwork += n; + if n == 0 { + break; + } + } + } + // timer.tick(); + + // no work: 20ns + // has work: <2us for a batch of 30 + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => nwork += n, + Status::Disconnected => break, + } + } + // timer.tick(); + + if fastrand::usize(..100) < 1 { + // 80-100ns, sometimes 200ns + if let Status::Disconnected = self.check_cmd().await? { + break; + } + // timer.tick(); + + // 50ns + self.check_input_cmd_queue()?; + // timer.tick(); + } + + self.indicator.set_nwork(nwork); + // log::info!("mrpc mainloop: {} {}", nwork, timer); + + future::yield_now().await; + } + + self.wait_outstanding_complete().await?; + Ok(()) + } +} + +impl MrpcLBEngine { + // we need to wait for RpcAdapter engine to finish outstanding send requests + // (whether successful or not), to release message meta pool and shutdown mRPC engine. + // However, we cannot indefinitely wait for it in case of wc errors. + async fn wait_outstanding_complete(&mut self) -> Result<(), DatapathError> { + use phoenix_common::engine::datapath::TryRecvError; + while !self.meta_buf_pool.is_full() { + match self.rx_inputs()[0].try_recv() { + Ok(msg) => match msg { + EngineRxMessage::Ack(rpc_id, _status) => { + // release the buffer whatever the status is. + self.meta_buf_pool.release(rpc_id)?; + } + EngineRxMessage::RpcMessage(_) => {} + EngineRxMessage::RecvError(..) => {} + }, + Err(TryRecvError::Disconnected) => return Ok(()), + Err(TryRecvError::Empty) => {} + } + future::yield_now().await; + } + Ok(()) + } + + async fn check_cmd(&mut self) -> Result { + match self.customer.try_recv_cmd() { + // handle request + Ok(req) => { + let result = self.process_cmd(&req).await; + match result { + Ok(Some(res)) => self.customer.send_comp(cmd::Completion(Ok(res)))?, + Ok(None) => return Ok(Progress(0)), + Err(e) => self.customer.send_comp(cmd::Completion(Err(e.into())))?, + } + Ok(Progress(1)) + } + Err(ipc::TryRecvError::Empty) => { + // do nothing + Ok(Progress(0)) + } + Err(ipc::TryRecvError::Disconnected) => Ok(Status::Disconnected), + Err(ipc::TryRecvError::Other(_e)) => Err(Error::IpcTryRecv), + } + } + + fn create_transport(&mut self, transport_type: control_plane::TransportType) { + self.transport_type = Some(transport_type); + } + + async fn process_cmd( + &mut self, + req: &cmd::Command, + ) -> Result, Error> { + use phoenix_api_mrpc::cmd::{Command, CompletionKind}; + match req { + Command::SetTransport(transport_type) => { + if self.transport_type.is_some() { + Err(Error::TransportType) + } else { + self.create_transport(*transport_type); + Ok(Some(CompletionKind::SetTransport)) + } + } + Command::Connect(addr) => { + self.cmd_tx.send(Command::Connect(*addr)).unwrap(); + Ok(None) + } + Command::MultiConnect(handles) => { + let copy_handle = handles.clone(); + self.cmd_tx + .send(Command::MultiConnect(copy_handle)) + .unwrap(); + Ok(None) + } + Command::Bind(addr) => { + self.cmd_tx.send(Command::Bind(*addr)).unwrap(); + Ok(None) + } + Command::NewMappedAddrs(conn_handle, app_vaddrs) => { + self.cmd_tx + .send(Command::NewMappedAddrs(*conn_handle, app_vaddrs.clone())) + .unwrap(); + Ok(None) + } + Command::UpdateProtos(protos) => { + let dylib_path = + build_serializer_lib(protos.clone(), self.dispatch_build_cache.clone())?; + self.cmd_tx + .send(Command::UpdateProtosInner(dylib_path)) + .unwrap(); + Ok(None) + } + Command::UpdateProtosInner(_) => { + panic!("UpdateProtosInner is only used in backend") + } + } + } + + fn check_customer(&mut self) -> Result { + use dp::WorkRequest; + let buffer_cap = self.wr_read_buffer.capacity(); + // let mut timer = crate::timer::Timer::new(); + + // 15ns + // Fetch available work requests. Copy them into a buffer. + let max_count = buffer_cap.min(self.customer.get_avail_wc_slots()?); + if max_count == 0 { + return Ok(Progress(0)); + } + // timer.tick(); + + // 300-10us, mostly 300ns (Vec::with_capacity()) + let mut count = 0; + // self.wr_read_buffer.clear(); + // SAFETY: dp::WorkRequest is Copy and zerocopy + unsafe { + self.wr_read_buffer.set_len(0); + } + + // timer.tick(); + + // 60-150ns + self.customer + .dequeue_wr_with(|ptr, read_count| unsafe { + // TODO(cjr): max_count <= read_count always holds + count = max_count.min(read_count); + for i in 0..count { + self.wr_read_buffer + .push(ptr.add(i).cast::().read()); + } + count + }) + .unwrap_or_else(|e| panic!("check_customer: {}", e)); + + // Process the work requests. + // timer.tick(); + + // no work: 10ns + // has work: 100-400ns + let buffer = mem::take(&mut self.wr_read_buffer); + + for wr in &buffer { + let ret = self.process_dp(wr); + match ret { + Ok(()) => {} + Err(e) => { + self.wr_read_buffer = buffer; + // TODO(cjr): error handling + return Err(e); + } + } + } + + self.wr_read_buffer = buffer; + + // timer.tick(); + // log::info!("check_customer: {} {}", count, timer); + + Ok(Progress(count)) + } + + fn process_dp(&mut self, req: &dp::WorkRequest) -> Result<(), DatapathError> { + use dp::WorkRequest; + + match req { + WorkRequest::Call(erased) | WorkRequest::Reply(erased) => { + // let mut timer = crate::timer::Timer::new(); + + // 1300ns, even if the tracing level is filtered shit!!!!!! + tracing::trace!( + "mRPC LB engine got a message from App, call_id: {:?}, conn_id: {:?}", + erased.meta.call_id, + erased.meta.conn_id, + ); + + // timer.tick(); + + // construct message meta on heap + let rpc_id = RpcId(erased.meta.conn_id, erased.meta.call_id); + let meta_buf_ptr = self + .meta_buf_pool + .obtain(rpc_id) + .expect("MessageMeta pool exhausted"); + + // timer.tick(); + + // copy the meta + unsafe { + std::ptr::write(meta_buf_ptr.as_meta_ptr(), erased.meta); + } + + let msg = RpcMessageTx { + meta_buf_ptr, + addr_backend: erased.shm_addr_backend, + }; + + // timer.tick(); + + // if access to message's data fields are desired, + // typed message can be conjured up here via matching func_id + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + + // timer.tick(); + // log::info!("process_dp call/reply: {}", timer); + } + WorkRequest::ReclaimRecvBuf(conn_id, msg_call_ids) => { + // let mut timer = crate::timer::Timer::new(); + + // 10-40ns, mostly 10ns + self.tx_outputs()[0] + .send(EngineTxMessage::ReclaimRecvBuf(*conn_id, *msg_call_ids))?; + + // timer.tick(); + // log::info!("process_dp reclaim recv buf: {}", timer); + } + } + Ok(()) + } + + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineRxMessage::RpcMessage(msg) => { + // let mut timer = crate::timer::Timer::new(); + let meta = unsafe { *msg.meta.as_ref() }; + tracing::trace!( + "mRPC LB engine send message to App, call_id={:?}, conn_id={:?}", + meta.call_id, + meta.conn_id + ); + + let erased = MessageErased { + meta, + shm_addr_app: msg.addr_app, + shm_addr_backend: msg.addr_backend, + }; + // timer.tick(); + match meta.status_code { + StatusCode::AccessDenied => { + tracing::debug!("Status code: Access denied, meta={:?}", meta); + let mut sent = false; + let rpc_id = RpcId(meta.conn_id, meta.call_id); + let status = phoenix_api::rpc::TransportStatus::Error(unsafe { + NonZeroU32::new_unchecked(402) + }); + while !sent { + self.customer.enqueue_wc_with(|ptr, _count| unsafe { + // self.customer.notify_wc_with(|ptr, _count| unsafe { + sent = true; + ptr.cast::() + .write(dp::Completion::Outgoing(rpc_id, status)); + 1 + })?; + } + let msg_call_ids = + [meta.call_id, meta.call_id, meta.call_id, meta.call_id]; + self.tx_outputs()[0].send(EngineTxMessage::ReclaimRecvBuf( + meta.conn_id, + msg_call_ids, + ))?; + } + StatusCode::Unknown => { + tracing::error!("Status code: Unknown error, meta={:?}", meta); + } + StatusCode::Success => { + // the following operation takes around 100ns + let mut sent = false; + while !sent { + self.customer.enqueue_wc_with(|ptr, _count| unsafe { + // self.customer.notify_wc_with(|ptr, _count| unsafe { + sent = true; + ptr.cast::() + .write(dp::Completion::Incoming(erased)); + 1 + })?; + } + } + } + + // timer.tick(); + // log::info!("MrpcEngine check_input_queue: {}", timer); + } + EngineRxMessage::Ack(rpc_id, status) => { + // release message meta buffer + self.meta_buf_pool.release(rpc_id)?; + let mut sent = false; + while !sent { + self.customer.enqueue_wc_with(|ptr, _count| unsafe { + // self.customer.notify_wc_with(|ptr, _count| unsafe { + sent = true; + ptr.cast::() + .write(dp::Completion::Outgoing(rpc_id, status)); + 1 + })?; + } + } + EngineRxMessage::RecvError(conn_id, status) => { + let mut sent = false; + while !sent { + self.customer.enqueue_wc_with(|ptr, _count| unsafe { + // self.customer.notify_wc_with(|ptr, _count| unsafe { + sent = true; + ptr.cast::() + .write(dp::Completion::RecvError(conn_id, status)); + 1 + })?; + } + } + } + Ok(Progress(1)) + } + Err(TryRecvError::Empty) => Ok(Progress(0)), + Err(TryRecvError::Disconnected) => Ok(Status::Disconnected), + } + } + + fn check_input_cmd_queue(&mut self) -> Result { + use phoenix_api_mrpc::cmd::{Completion, CompletionKind}; + use tokio::sync::mpsc::error::TryRecvError; + match self.cmd_rx.try_recv() { + Ok(Completion(comp)) => { + match comp { + // server new incoming connection + Ok(CompletionKind::NewConnectionInternal(conn_resp, fds)) => { + // TODO(cjr): check if this send_fd will block indefinitely. + self.customer.send_fd(&fds).unwrap(); + let comp_kind = CompletionKind::NewConnection(conn_resp); + self.customer.send_comp(cmd::Completion(Ok(comp_kind)))?; + Ok(Status::Progress(1)) + } + // client connection response + Ok(CompletionKind::ConnectInternal(conn_resp, fds)) => { + self.customer.send_fd(&fds).unwrap(); + let comp_kind = CompletionKind::Connect(conn_resp); + self.customer.send_comp(cmd::Completion(Ok(comp_kind)))?; + Ok(Status::Progress(1)) + } + Ok(CompletionKind::MultiConnect(handle)) => { + let comp_kind = CompletionKind::MultiConnect(handle); + self.customer.send_comp(cmd::Completion(Ok(comp_kind)))?; + Ok(Status::Progress(1)) + } + // server bind response + c @ Ok( + CompletionKind::Bind(..) + | CompletionKind::NewMappedAddrs + | CompletionKind::UpdateProtos, + ) => { + self.customer.send_comp(cmd::Completion(c))?; + Ok(Status::Progress(1)) + } + other => panic!("unexpected: {:?}", other), + } + } + Err(TryRecvError::Empty) => Ok(Progress(0)), + Err(TryRecvError::Disconnected) => Ok(Status::Disconnected), + } + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/lib.rs b/experimental/mrpc/plugin/mrpclb/src/lib.rs new file mode 100644 index 00000000..ffbef7a9 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/lib.rs @@ -0,0 +1,78 @@ +#![feature(ptr_internals)] +#![feature(peer_credentials_unix_socket)] + +use thiserror::Error; + +use phoenix_common::resource::Error as ResourceError; +pub use phoenix_common::{InitFnResult, PhoenixModule}; + +pub mod builder; +pub mod config; +pub(crate) mod engine; +// pub mod message; +// pub mod meta_pool; +pub mod module; +pub mod state; +pub mod unpack; + +#[derive(Debug, Error)] +pub(crate) enum Error { + // Below are errors that return to the user. + #[error("Failed to set transport type")] + TransportType, + #[error("Resource error: {0}")] + Resource(#[from] ResourceError), + + // Below are errors that does not return to the user. + #[error("ipc-channel TryRecvError")] + IpcTryRecv, + #[error("Customer error: {0}")] + Customer(#[from] ipc::Error), + #[error("Build marshal library failed: {0}")] + MarshalLibBuilder(#[from] builder::Error), +} + +impl From for phoenix_api::Error { + fn from(other: Error) -> Self { + phoenix_api::Error::Generic(other.to_string()) + } +} + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Shared memory queue error: {0}.")] + ShmIpc(#[from] ipc::shmem_ipc::ShmIpcError), + #[error("Shared memory queue ringbuf error: {0}.")] + ShmRingbuf(#[from] ipc::shmem_ipc::ShmRingbufError), + #[error("Resource error: {0}")] + Resource(#[from] ResourceError), + #[error("Internal queue send error")] + InternalQueueSend, +} + +impl From for DatapathError { + fn from(other: ipc::Error) -> Self { + match other { + ipc::Error::ShmIpc(e) => DatapathError::ShmIpc(e), + ipc::Error::ShmRingbuf(e) => DatapathError::ShmRingbuf(e), + _ => panic!(), + } + } +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::MrpcLBConfig; +use crate::module::MrpcLBModule; + +#[no_mangle] +pub fn init_module(config_string: Option<&str>) -> InitFnResult> { + let config = MrpcLBConfig::new(config_string)?; + let module = MrpcLBModule::new(config); + Ok(Box::new(module)) +} diff --git a/experimental/mrpc/plugin/mrpclb/src/module.rs b/experimental/mrpc/plugin/mrpclb/src/module.rs new file mode 100644 index 00000000..fd31b845 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/module.rs @@ -0,0 +1,341 @@ +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::Arc; + +use anyhow::{bail, Result}; +use uuid::Uuid; + +use ipc::customer::ShmCustomer; +use phoenix_api::engine::SchedulingMode; +use phoenix_api_mrpc::control_plane::Setting; +use phoenix_api_mrpc::control_plane::TransportType; +use phoenix_api_mrpc::{cmd, dp}; + +use phoenix_common::engine::datapath::meta_pool::MetaBufferPool; +use phoenix_common::engine::datapath::node::{ChannelDescriptor, DataPathNode}; +use phoenix_common::engine::{Engine, EnginePair, EngineType}; +use phoenix_common::log; +use phoenix_common::module::{ + ModuleCollection, ModuleDowncast, NewEngineRequest, PhoenixModule, Service, ServiceInfo, + Version, +}; +use phoenix_common::state_mgr::{Pid, SharedStateManager}; +use phoenix_common::storage::{get_default_prefix, ResourceCollection, SharedStorage}; +use phoenix_common::PhoenixResult; + +use crate::config::MrpcLBConfig; + +use super::engine::MrpcLBEngine; +use super::state::{Shared, State}; + +pub type CustomerType = + ShmCustomer; + +pub(crate) struct MrpcLBEngineBuilder { + customer: CustomerType, + _client_pid: Pid, + mode: SchedulingMode, + cmd_tx: tokio::sync::mpsc::UnboundedSender, + cmd_rx: tokio::sync::mpsc::UnboundedReceiver, + node: DataPathNode, + serializer_build_cache: PathBuf, + shared: Arc, +} + +impl MrpcLBEngineBuilder { + #[allow(clippy::too_many_arguments)] + fn new( + customer: CustomerType, + client_pid: Pid, + mode: SchedulingMode, + cmd_tx: tokio::sync::mpsc::UnboundedSender, + cmd_rx: tokio::sync::mpsc::UnboundedReceiver, + node: DataPathNode, + serializer_build_cache: PathBuf, + shared: Arc, + ) -> Self { + MrpcLBEngineBuilder { + customer, + cmd_tx, + cmd_rx, + node, + _client_pid: client_pid, + mode, + serializer_build_cache, + shared, + } + } + + fn build(self) -> Result { + const META_BUFFER_POOL_CAP: usize = 128; + const BUF_LEN: usize = 32; + + let state = State::new(self.shared); + + Ok(MrpcLBEngine { + _state: state, + customer: self.customer, + cmd_tx: self.cmd_tx, + cmd_rx: self.cmd_rx, + node: self.node, + meta_buf_pool: MetaBufferPool::new(META_BUFFER_POOL_CAP), + _mode: self.mode, + dispatch_build_cache: self.serializer_build_cache, + transport_type: Some(TransportType::Tcp), + indicator: Default::default(), + wr_read_buffer: Vec::with_capacity(BUF_LEN), + }) + } +} + +pub struct MrpcLBModule { + config: MrpcLBConfig, + pub state_mgr: SharedStateManager, +} + +impl MrpcLBModule { + pub const MRPCLB_ENGINE: EngineType = EngineType("MrpcLBEngine"); + pub const LB_ENGINE: EngineType = EngineType("LoadBalancerEngine"); + pub const ENGINES: &'static [EngineType] = &[MrpcLBModule::MRPCLB_ENGINE]; + pub const DEPENDENCIES: &'static [EnginePair] = &[ + ( + MrpcLBModule::MRPCLB_ENGINE, + EngineType("LoadBalancerEngine"), + ), + ( + EngineType("LoadBalancerEngine"), + EngineType("RpcAdapterEngine"), + ), + ]; + + pub const SERVICE: Service = Service("MrpcLB"); + pub const TX_CHANNELS: &'static [ChannelDescriptor] = &[ + ChannelDescriptor(MrpcLBModule::MRPCLB_ENGINE, MrpcLBModule::LB_ENGINE, 0, 0), + ChannelDescriptor( + MrpcLBModule::LB_ENGINE, + EngineType("RpcAdapterEngine"), + 0, + 0, + ), + ]; + pub const RX_CHANNELS: &'static [ChannelDescriptor] = &[ + ChannelDescriptor( + EngineType("RpcAdapterEngine"), + MrpcLBModule::LB_ENGINE, + 0, + 0, + ), + ChannelDescriptor(MrpcLBModule::LB_ENGINE, MrpcLBModule::MRPCLB_ENGINE, 0, 0), + ]; + + pub const TCP_DEPENDENCIES: &'static [EnginePair] = &[ + ( + MrpcLBModule::MRPCLB_ENGINE, + EngineType("LoadBalancerEngine"), + ), + ( + EngineType("LoadBalancerEngine"), + EngineType("TcpRpcAdapterEngine"), + ), + ]; + pub const TCP_TX_CHANNELS: &'static [ChannelDescriptor] = &[ + ChannelDescriptor(MrpcLBModule::MRPCLB_ENGINE, MrpcLBModule::LB_ENGINE, 0, 0), + ChannelDescriptor( + MrpcLBModule::LB_ENGINE, + EngineType("TcpRpcAdapterEngine"), + 0, + 0, + ), + ]; + pub const TCP_RX_CHANNELS: &'static [ChannelDescriptor] = &[ + ChannelDescriptor( + EngineType("TcpRpcAdapterEngine"), + MrpcLBModule::LB_ENGINE, + 0, + 0, + ), + ChannelDescriptor(MrpcLBModule::LB_ENGINE, MrpcLBModule::MRPCLB_ENGINE, 0, 0), + ]; +} + +impl MrpcLBModule { + pub fn new(config: MrpcLBConfig) -> Self { + MrpcLBModule { + config, + state_mgr: SharedStateManager::new(), + } + } + + // Returns build_cache if it's already an absolute path. Otherwise returns the path relative + // to the engine's prefix. + fn get_build_cache_directory(&self, engine_prefix: &PathBuf) -> PathBuf { + let build_cache = self.config.build_cache.clone(); + if build_cache.is_absolute() { + build_cache + } else { + engine_prefix.join(build_cache) + } + } +} + +impl PhoenixModule for MrpcLBModule { + fn service(&self) -> Option { + let service = if self.config.transport == TransportType::Tcp { + let group = vec![ + Self::MRPCLB_ENGINE, + Self::LB_ENGINE, + EngineType("TcpRpcAdapterEngine"), + ]; + ServiceInfo { + service: MrpcLBModule::SERVICE, + engine: MrpcLBModule::MRPCLB_ENGINE, + tx_channels: MrpcLBModule::TCP_TX_CHANNELS, + rx_channels: MrpcLBModule::TCP_RX_CHANNELS, + scheduling_groups: vec![group], + } + } else { + let group = vec![ + Self::MRPCLB_ENGINE, + Self::LB_ENGINE, + EngineType("RpcAdapterEngine"), + ]; + ServiceInfo { + service: MrpcLBModule::SERVICE, + engine: MrpcLBModule::MRPCLB_ENGINE, + tx_channels: MrpcLBModule::TX_CHANNELS, + rx_channels: MrpcLBModule::RX_CHANNELS, + scheduling_groups: vec![group], + } + }; + Some(service) + } + + fn engines(&self) -> &[EngineType] { + MrpcLBModule::ENGINES + } + + fn dependencies(&self) -> &[EnginePair] { + if self.config.transport == TransportType::Tcp { + MrpcLBModule::TCP_DEPENDENCIES + } else { + MrpcLBModule::DEPENDENCIES + } + } + + fn check_compatibility(&self, _prev: Option<&Version>, _curr: &HashMap<&str, Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let module = *self; + let mut collections = ResourceCollection::new(); + collections.insert("state_mgr".to_string(), Box::new(module.state_mgr)); + collections.insert("config".to_string(), Box::new(module.config)); + collections + } + + fn migrate(&mut self, prev_module: Box) { + // NOTE(wyj): we may better call decompose here + let prev_concrete = unsafe { *prev_module.downcast_unchecked::() }; + self.state_mgr = prev_concrete.state_mgr; + } + + fn create_engine( + &mut self, + ty: EngineType, + request: NewEngineRequest, + shared: &mut SharedStorage, + global: &mut ResourceCollection, + node: DataPathNode, + _plugged: &ModuleCollection, + ) -> PhoenixResult>> { + if ty != MrpcLBModule::MRPCLB_ENGINE { + bail!("invalid engine type {:?}", ty) + } + if let NewEngineRequest::Service { + sock, + client_path, + mode, + cred, + config_string, + } = request + { + // generate a path and bind a unix domain socket to it + let uuid = Uuid::new_v4(); + let instance_name = format!("{}-{}.sock", self.config.engine_basename, uuid); + + // use the phoenix_prefix if not otherwise specified + let phoenix_prefix = get_default_prefix(global)?; + let engine_prefix = self.config.prefix.as_ref().unwrap_or(phoenix_prefix); + let engine_path = engine_prefix.join(instance_name); + + // get the directory of build cache + let build_cache = self.get_build_cache_directory(engine_prefix); + + // create customer stub + let customer = ShmCustomer::accept(sock, client_path, mode, engine_path)?; + + let client_pid = Pid::from_raw(cred.pid.unwrap()); + let shared_state = self.state_mgr.get_or_create(client_pid)?; + + let setting = if let Some(config_string) = config_string { + serde_json::from_str(&config_string)? + } else { + Setting { + transport: self.config.transport, + nic_index: self.config.nic_index, + core_id: None, + module_config: None, + } + }; + log::debug!("mRPCLB service setting: {:?}", setting); + + let engine_type = match setting.transport { + TransportType::Tcp => EngineType("TcpRpcAdapterEngine"), + TransportType::Rdma => EngineType("RpcAdapterEngine"), + }; + + // obtain senders/receivers of command queues with RpcAdapterEngine + // the sender/receiver ends are already created, + // as the RpcAdapterEngine is built first + // according to the topological order + let cmd_tx = shared.command_path.get_sender(&MrpcLBModule::LB_ENGINE)?; + let cmd_rx: tokio::sync::mpsc::UnboundedReceiver = + shared.command_path.get_receiver(&MrpcLBModule::LB_ENGINE)?; + + let builder = MrpcLBEngineBuilder::new( + customer, + client_pid, + mode, + cmd_tx, + cmd_rx, + node, + build_cache, + shared_state, + // TODO(cjr): store the setting, not necessary now. + ); + let engine = builder.build()?; + + Ok(Some(Box::new(engine))) + } else { + bail!("invalid request type"); + } + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + shared: &mut SharedStorage, + global: &mut ResourceCollection, + node: DataPathNode, + plugged: &ModuleCollection, + prev_version: Version, + ) -> PhoenixResult> { + if ty != MrpcLBModule::MRPCLB_ENGINE { + bail!("invalid engine type {:?}", ty) + } + let engine = MrpcLBEngine::restore(local, shared, global, node, plugged, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/state.rs b/experimental/mrpc/plugin/mrpclb/src/state.rs new file mode 100644 index 00000000..c3fed79f --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/state.rs @@ -0,0 +1,32 @@ +use std::io; +use std::sync::Arc; + +use phoenix_common::state_mgr::{Pid, ProcessShared}; + +pub(crate) struct State { + pub(crate) _shared: Arc, +} + +impl State { + pub(crate) fn new(shared: Arc) -> Self { + State { _shared: shared } + } +} + +#[allow(clippy::manual_non_exhaustive)] +pub struct Shared { + pub pid: Pid, + _other_state: (), +} + +impl ProcessShared for Shared { + type Err = io::Error; + + fn new(pid: Pid) -> io::Result { + let shared = Shared { + pid, + _other_state: (), + }; + Ok(shared) + } +} diff --git a/experimental/mrpc/plugin/mrpclb/src/unpack.rs b/experimental/mrpc/plugin/mrpclb/src/unpack.rs new file mode 100644 index 00000000..10255900 --- /dev/null +++ b/experimental/mrpc/plugin/mrpclb/src/unpack.rs @@ -0,0 +1,26 @@ +use std::ptr::Unique; + +use mrpc_marshal::{SgE, UnmarshalError}; +use phoenix_api::rpc::MessageMeta; + +pub trait UnpackFromSgE: Sized { + /// # Safety + /// + /// This operation may be zero-copy. Thus, the user must ensure the underlying data remain + /// valid after unpacking. + unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError>; +} + +impl UnpackFromSgE for MessageMeta { + unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError> { + if sge.len != std::mem::size_of::() { + return Err(UnmarshalError::SgELengthMismatch { + expected: std::mem::size_of::(), + actual: sge.len, + }); + } + let ptr = sge.ptr as *mut Self; + let meta = Unique::new(ptr).unwrap(); + Ok(meta) + } +} diff --git a/experimental/mrpc/plugin/rpc_adapter/src/engine.rs b/experimental/mrpc/plugin/rpc_adapter/src/engine.rs index ea55946e..93746cbf 100644 --- a/experimental/mrpc/plugin/rpc_adapter/src/engine.rs +++ b/experimental/mrpc/plugin/rpc_adapter/src/engine.rs @@ -1081,6 +1081,9 @@ impl RpcAdapterEngine { cmd::Command::UpdateProtos(_) => { unreachable!(); } + cmd::Command::MultiConnect(_) => { + unreachable!(); + } } } } diff --git a/experimental/mrpc/plugin/rpc_adapter/src/module.rs b/experimental/mrpc/plugin/rpc_adapter/src/module.rs index 274da195..81641e22 100644 --- a/experimental/mrpc/plugin/rpc_adapter/src/module.rs +++ b/experimental/mrpc/plugin/rpc_adapter/src/module.rs @@ -248,7 +248,7 @@ impl PhoenixModule for RpcAdapterModule { let (comp_sender, comp_receiver) = tokio::sync::mpsc::unbounded_channel(); shared .command_path - .put_receiver(EngineType("MrpcEngine"), comp_receiver)?; + .put_receiver(Self::RPC_ADAPTER_ENGINE, comp_receiver)?; let engine = self.create_rpc_adapter_engine( mode, diff --git a/experimental/mrpc/plugin/tcp_rpc_adapter/src/engine.rs b/experimental/mrpc/plugin/tcp_rpc_adapter/src/engine.rs index 19273c0b..8271420b 100644 --- a/experimental/mrpc/plugin/tcp_rpc_adapter/src/engine.rs +++ b/experimental/mrpc/plugin/tcp_rpc_adapter/src/engine.rs @@ -832,6 +832,7 @@ impl TcpRpcAdapterEngine { }; Ok(CompletionKind::ConnectInternal(conn_resp, fds)) } + Command::Bind(addr) => { log::debug!("Bind, addr: {:?}", addr); let handle = get_ops().bind(addr)?; @@ -846,6 +847,9 @@ impl TcpRpcAdapterEngine { Command::UpdateProtos(_) => { unreachable!(); } + Command::MultiConnect(_) => { + unreachable!(); + } } } } diff --git a/experimental/mrpc/plugin/tcp_rpc_adapter/src/module.rs b/experimental/mrpc/plugin/tcp_rpc_adapter/src/module.rs index 22d0edc7..f9b79cba 100644 --- a/experimental/mrpc/plugin/tcp_rpc_adapter/src/module.rs +++ b/experimental/mrpc/plugin/tcp_rpc_adapter/src/module.rs @@ -169,13 +169,16 @@ impl PhoenixModule for TcpRpcAdapterModule { } = request { let (cmd_sender, cmd_receiver) = tokio::sync::mpsc::unbounded_channel(); + shared .command_path .put_sender(Self::TCP_RPC_ADAPTER_ENGINE, cmd_sender)?; + let (comp_sender, comp_receiver) = tokio::sync::mpsc::unbounded_channel(); + shared .command_path - .put_receiver(EngineType("MrpcEngine"), comp_receiver)?; + .put_receiver(Self::TCP_RPC_ADAPTER_ENGINE, comp_receiver)?; let engine = self.create_rpc_adapter_engine( mode, diff --git a/experimental/mrpc/src/lib.rs b/experimental/mrpc/src/lib.rs index 24312414..0fa1a9c9 100644 --- a/experimental/mrpc/src/lib.rs +++ b/experimental/mrpc/src/lib.rs @@ -119,11 +119,16 @@ pub(crate) struct Context { impl Context { fn register(setting: &Setting) -> Result { let protos = RefCell::new(BTreeSet::new()); + println!("mrpc register: {:?}", setting); let setting_str = serde_json::to_string(setting)?; + let mut service = "Mrpc".to_string(); + if let Some(name) = &setting.module_config { + service = name.clone(); + } let service = ShmService::register( &*PHOENIX_PREFIX, &*PHOENIX_CONTROL_SOCK, - "Mrpc".to_string(), + service, SCHEDULING_HINT.with_borrow(|h| *h), Some(&setting_str), )?; diff --git a/experimental/mrpc/src/rheap.rs b/experimental/mrpc/src/rheap.rs index a148c585..73c4c169 100644 --- a/experimental/mrpc/src/rheap.rs +++ b/experimental/mrpc/src/rheap.rs @@ -52,6 +52,13 @@ impl ReadHeap { } } + pub fn default() -> Self { + ReadHeap { + rref_cnt: AtomicUsize::new(0), + rbufs: Vec::new(), + } + } + #[inline] pub(crate) fn increment_refcnt(&self) { self.rref_cnt.fetch_add(1, Ordering::Release); diff --git a/experimental/mrpc/src/stub/client.rs b/experimental/mrpc/src/stub/client.rs index fa668ed5..27f1b980 100644 --- a/experimental/mrpc/src/stub/client.rs +++ b/experimental/mrpc/src/stub/client.rs @@ -1,14 +1,16 @@ //! Client implementation. +use std::collections::HashMap; use std::future::Future; +use std::hash::Hash; use std::marker::PhantomData; -use std::net::ToSocketAddrs; +use std::net::{SocketAddr, ToSocketAddrs}; use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; use ipc::channel::{Receiver, TryRecvError}; use phoenix_api::rpc::{CallId, MessageErased, MessageMeta, RpcId, RpcMsgType, TransportStatus}; -use phoenix_api::AsHandle; +use phoenix_api::{AsHandle, Handle}; use phoenix_api_mrpc::cmd::{Command, CompletionKind}; use phoenix_api_mrpc::dp; use phoenix_syscalls::_rx_recv_impl as rx_recv_impl; @@ -61,7 +63,9 @@ impl<'a, T: Unpin> Future for ReqFuture<'a, T> { ); let read_heap = this .client - .conn + .conns + .get(&reply.meta.conn_id) + .unwrap() .map_alive(|alive| Arc::clone(&alive.read_heap)) .expect("TODO: return an error when connection is dead rather than panic"); Ok(RRef::new(reply, read_heap)) @@ -84,9 +88,10 @@ impl !Sync for ClientStub {} /// [`mrpc-build`]: ../../../doc/mrpc_build/index.html #[derive(Debug)] pub struct ClientStub { + vconn: Connection, // A connection could go into error state, in that case, all subsequent operations over this // connection would return an error. - conn: Connection, + conns: HashMap, // inner: RefCell, inner: spin::Mutex, } @@ -113,7 +118,7 @@ impl ClientStub { Req: RpcData, Res: Unpin + RpcData, { - let conn_id = self.conn.handle(); + let conn_id = self.master_conn().handle(); // construct meta let meta = MessageMeta { @@ -174,11 +179,13 @@ impl ClientStub { TransportStatus::Error(code) => match code.get() { 402 => {} _ => { - self.conn.map_alive(|alive| alive.pending.remove(&rpc_id))?; + self.master_conn() + .map_alive(|alive| alive.pending.remove(&rpc_id))?; } }, _ => { - self.conn.map_alive(|alive| alive.pending.remove(&rpc_id))?; + self.master_conn() + .map_alive(|alive| alive.pending.remove(&rpc_id))?; } } @@ -196,7 +203,7 @@ impl ClientStub { conn_id, status ); - self.conn.close(); + self.master_conn().close(); } } @@ -237,11 +244,12 @@ impl ClientStub { // self.conn // .hold_rpc(RpcId::new(meta.conn_id, meta.call_id), WRef::clone(&msg))?; - self.conn.map_alive(|alive| { - alive - .pending - .insert(RpcId::new(meta.conn_id, meta.call_id), WRef::clone(&msg)) - })?; + self.master_conn() + .map_alive(|alive: &crate::stub::conn::AliveConnection| { + alive + .pending + .insert(RpcId::new(meta.conn_id, meta.call_id), WRef::clone(&msg)) + })?; // construct the request let (ptr_app, ptr_backend) = msg.into_shmptr().to_raw_parts(); @@ -275,6 +283,13 @@ impl ClientStub { }) } + fn master_conn(&self) -> &Connection { + if self.vconn.handle().is_master() { + &self.vconn + } else { + self.conns.get(&self.vconn.handle()).unwrap() + } + } /// Creates an RPC client by connecting to a given socket address. // TODO(cjr): Change this to async too pub fn connect(addr: A) -> Result { @@ -311,8 +326,11 @@ impl ClientStub { let (stub_id, receiver) = LOCAL_REACTOR.with_borrow_mut(|r| r.register_stub()); LOCAL_REACTOR.with_borrow_mut(|r| r.register_connection(stub_id, &conn)); + let mut conns = HashMap::new(); + conns.insert(conn.handle().clone(), conn); Ok(Self { - conn, + vconn: Connection::vconn(conn_handle), + conns: conns, // inner: RefCell::new(Inner { inner: spin::Mutex::new(Inner { receiver, @@ -322,4 +340,88 @@ impl ClientStub { }) }) } + + /// Creates an RPC client by connecting to multiple socket address. + pub fn multi_connect(addrs: Vec) -> Result { + let connect_addrs: Vec = addrs + .iter() + .map(|addr| addr.to_socket_addrs()) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); + let mut conns = Vec::new(); + let mut handles = Vec::new(); + let mut vconn = None; + for addr in connect_addrs { + let cmd = Command::Connect(addr); + MRPC_CTX.with(|ctx| { + ctx.service.send_cmd(cmd).unwrap(); + let fds = ctx.service.recv_fd().unwrap(); + match ctx.service.recv_comp().unwrap().0 { + Ok(CompletionKind::Connect(conn_resp)) => { + assert_eq!(fds.len(), conn_resp.read_regions.len()); + + let conn_handle = conn_resp.conn_handle; + + let read_heap = ReadHeap::new(&conn_resp, &fds); + let vaddrs = read_heap + .rbufs + .iter() + .map(|rbuf| (rbuf.as_handle(), rbuf.as_ptr().expose_addr())) + .collect(); + + // return the mapped addr back + let req = Command::NewMappedAddrs(conn_handle, vaddrs); + ctx.service.send_cmd(req).unwrap(); + // wait for the reply! + match ctx.service.recv_comp().unwrap().0 { + Ok(CompletionKind::NewMappedAddrs) => {} + Err(e) => panic!("{:?}", e), + _ => panic!("unmatched branch"), + } + + // register the stub with the reactor + let conn = Connection::new(conn_handle, read_heap); + handles.push(conn.handle().clone()); + conns.push(conn); + } + Err(e) => { + panic!("{:?}", e) + } + _ => panic!("unmatched branch"), + } + }); + } + MRPC_CTX.with(|ctx| { + let cmd = Command::MultiConnect(handles); + ctx.service.send_cmd(cmd).unwrap(); + match ctx.service.recv_comp().unwrap().0 { + Ok(CompletionKind::MultiConnect(handle)) => { + //assert!(handle == Handle::MASTER); + _ = vconn.insert(Connection::vconn(handle)); + } + Err(e) => panic!("{:?}", e), + _ => panic!("unmatched branch"), + } + }); + let (stub_id, receiver) = LOCAL_REACTOR.with_borrow_mut(|r| r.register_stub()); + for conn in &conns { + LOCAL_REACTOR.with_borrow_mut(|r| r.register_connection(stub_id, conn)); + } + let rv = vconn.as_ref().unwrap(); + LOCAL_REACTOR.with_borrow_mut(|r| r.register_connection(stub_id, rv)); + let mut conn_map = HashMap::new(); + for conn in conns { + conn_map.insert(conn.handle().clone(), conn); + } + Ok(Self { + vconn: vconn.unwrap(), + conns: conn_map, + inner: spin::Mutex::new(Inner { + receiver, + reply_cache: ReplyCache::new(), + }), + }) + } } diff --git a/experimental/mrpc/src/stub/conn.rs b/experimental/mrpc/src/stub/conn.rs index 81b7275a..10c08aaa 100644 --- a/experimental/mrpc/src/stub/conn.rs +++ b/experimental/mrpc/src/stub/conn.rs @@ -54,6 +54,15 @@ impl Connection { } } + pub(crate) fn vconn(handle: Handle) -> Self { + Connection { + inner: RefCell::new(Inner::Alive(AliveConnection::new( + handle, + ReadHeap::default(), + ))), + } + } + pub(crate) fn close(&self) { let mut inner = self.inner.borrow_mut(); match &mut *inner { diff --git a/src/phoenix-api/core/src/handle.rs b/src/phoenix-api/core/src/handle.rs index 4df6eaaf..0f302c7a 100644 --- a/src/phoenix-api/core/src/handle.rs +++ b/src/phoenix-api/core/src/handle.rs @@ -8,6 +8,10 @@ pub struct Handle(pub u64); impl Handle { pub const INVALID: Handle = Handle(u64::MAX); + pub const MASTER: Handle = Handle(u64::MAX - 1); + pub fn is_master(&self) -> bool { + self.0 == Self::MASTER.0 + } } pub trait AsHandle { diff --git a/src/phoenixos/src/control.rs b/src/phoenixos/src/control.rs index 6a9c1570..5c136bdf 100644 --- a/src/phoenixos/src/control.rs +++ b/src/phoenixos/src/control.rs @@ -146,11 +146,11 @@ impl Control { service, pid ); - let node = nodes + let node: DataPathNode = nodes .remove(aux_engine_type) .unwrap_or_else(DataPathNode::new); let specified_mode = specified_mode.unwrap_or(service_mode); - let request = NewEngineRequest::Auxiliary { + let request: NewEngineRequest<'_> = NewEngineRequest::Auxiliary { pid, mode: specified_mode, config_string: config_string.clone(), From 02affe63a2c0c09f77b62cf5e170caf49c7fd825 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 23 Oct 2023 09:11:44 -0400 Subject: [PATCH 08/21] admission control --- eval/policy/admission-control/attach1.toml | 33 +++ eval/policy/admission-control/attach2.toml | 33 +++ eval/policy/admission-control/detach.toml | 4 + experimental/mrpc/Cargo.lock | 123 ++++++++- experimental/mrpc/Cargo.toml | 10 + experimental/mrpc/load-mrpc-plugins.toml | 20 ++ .../policy/admission-control/Cargo.toml | 11 + .../admission-control/src/control_plane.rs | 14 + .../policy/admission-control/src/lib.rs | 1 + .../policy/admission-control/Cargo.toml | 28 ++ .../policy/admission-control/src/config.rs | 12 + .../policy/admission-control/src/engine.rs | 245 ++++++++++++++++++ .../policy/admission-control/src/lib.rs | 34 +++ .../policy/admission-control/src/module.rs | 103 ++++++++ .../policy/admission-control/src/rpc_hello.rs | 29 +++ 15 files changed, 699 insertions(+), 1 deletion(-) create mode 100644 eval/policy/admission-control/attach1.toml create mode 100644 eval/policy/admission-control/attach2.toml create mode 100644 eval/policy/admission-control/detach.toml create mode 100644 experimental/mrpc/phoenix-api/policy/admission-control/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/admission-control/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/admission-control/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/admission-control/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/admission-control/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/admission-control/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/admission-control/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/admission-control/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/admission-control/src/rpc_hello.rs diff --git a/eval/policy/admission-control/attach1.toml b/eval/policy/admission-control/attach1.toml new file mode 100644 index 00000000..460dc5c6 --- /dev/null +++ b/eval/policy/admission-control/attach1.toml @@ -0,0 +1,33 @@ +addon_engine = "HelloAclSenderEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "HelloAclSenderEngine", + 0, + 0, + ], + [ + "HelloAclSenderEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "HelloAclSenderEngine", + 0, + 0, + ], + [ + "HelloAclSenderEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +''' diff --git a/eval/policy/admission-control/attach2.toml b/eval/policy/admission-control/attach2.toml new file mode 100644 index 00000000..fe3147f4 --- /dev/null +++ b/eval/policy/admission-control/attach2.toml @@ -0,0 +1,33 @@ +addon_engine = "AdmissionControlEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "AdmissionControlEngine", + 0, + 0, + ], + [ + "AdmissionControlEngine", + "HelloAclSenderEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "HelloAclSenderEngine", + "AdmissionControlEngine", + 0, + 0, + ], + [ + "AdmissionControlEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "HelloAclSenderEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +''' diff --git a/eval/policy/admission-control/detach.toml b/eval/policy/admission-control/detach.toml new file mode 100644 index 00000000..48793f78 --- /dev/null +++ b/eval/policy/admission-control/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "HelloAclSenderEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [] +op = "detach" diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 826584cc..da65e132 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1576,6 +1576,29 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phoenix-admission-control" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-admission-control", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-api" version = "0.1.0" @@ -1623,6 +1646,14 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "phoenix-api-policy-admission-control" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-hello-acl-receiver" version = "0.1.0" @@ -1655,6 +1686,22 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-metrics" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + +[[package]] +name = "phoenix-api-policy-mutation" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-null" version = "0.1.0" @@ -1849,6 +1896,28 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-metrics" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-hello-acl-sender", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-mrpc" version = "0.1.0" @@ -1913,6 +1982,28 @@ dependencies = [ "uuid", ] +[[package]] +name = "phoenix-mutation" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-hello-acl-sender", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-null" version = "0.1.0" @@ -2295,11 +2386,22 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", + "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2310,6 +2412,16 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -2334,6 +2446,15 @@ dependencies = [ "getrandom 0.1.16", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.8", +] + [[package]] name = "rand_hc" version = "0.2.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 8979240a..0d87b91f 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -56,6 +56,9 @@ members = [ "phoenix-api/policy/logging", "phoenix-api/policy/hello-acl-receiver", "phoenix-api/policy/hello-acl-sender", + "phoenix-api/policy/admission-control", + "phoenix-api/policy/metrics", + "phoenix-api/policy/mutation", # the pheonix plugins "plugin/mrpc", "plugin/mrpclb", @@ -70,6 +73,9 @@ members = [ "plugin/policy/hotel-acl", "plugin/policy/hello-acl-receiver", "plugin/policy/hello-acl-sender", + "plugin/policy/admission-control", + "plugin/policy/metrics", + "plugin/policy/mutation", # examples "examples/rpc_echo", "examples/rpc_bench", @@ -96,6 +102,9 @@ phoenix-api-policy-hotel-acl = { path = "phoenix-api/policy/hotel-acl" } phoenix-api-policy-logging = { path = "phoenix-api/policy/logging" } phoenix-api-policy-hello-acl-receiver = { path = "phoenix-api/policy/hello-acl-receiver" } phoenix-api-policy-hello-acl-sender = { path = "phoenix-api/policy/hello-acl-sender" } +phoenix-api-policy-admission-control = { path = "phoenix-api/policy/admission-control" } +phoenix-api-policy-metrics = { path = "phoenix-api/policy/metrics" } +phoenix-api-policy-mutation = { path = "phoenix-api/policy/mutation" } mrpc-build = { path = "mrpc-build" } mrpc-derive = { path = "mrpc-derive" } @@ -169,6 +178,7 @@ fasthash = "0.4.0" link-cplusplus = "1.0" arc-swap = "1.5.0" crossbeam-utils = "0.8.12" +rand = "0.8" [profile.release] debug = true diff --git a/experimental/mrpc/load-mrpc-plugins.toml b/experimental/mrpc/load-mrpc-plugins.toml index 1841c039..2a929dc5 100644 --- a/experimental/mrpc/load-mrpc-plugins.toml +++ b/experimental/mrpc/load-mrpc-plugins.toml @@ -80,3 +80,23 @@ name = "HelloAclSender" lib_path = "plugins/libphoenix_hello_acl_sender.rlib" config_string = ''' ''' + +[[addons]] +name = "AdmissionControl" +lib_path = "plugins/libphoenix_admission_control.rlib" +config_string = ''' +''' + +[[addons]] +name = "Metrics" +lib_path = "plugins/libphoenix_metrics.rlib" +config_string = ''' +''' + +[[addons]] +name = "Mutation" +lib_path = "plugins/libphoenix_mutation.rlib" +config_string = ''' +''' + +[[addons]] diff --git a/experimental/mrpc/phoenix-api/policy/admission-control/Cargo.toml b/experimental/mrpc/phoenix-api/policy/admission-control/Cargo.toml new file mode 100644 index 00000000..c94e4fc1 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/admission-control/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-admission-control" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/admission-control/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/admission-control/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/admission-control/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/admission-control/src/lib.rs b/experimental/mrpc/phoenix-api/policy/admission-control/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/admission-control/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/plugin/policy/admission-control/Cargo.toml b/experimental/mrpc/plugin/policy/admission-control/Cargo.toml new file mode 100644 index 00000000..3e776fc8 --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "phoenix-admission-control" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +phoenix-api-policy-admission-control.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true + +phoenix_common.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +fnv.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/plugin/policy/admission-control/src/config.rs b/experimental/mrpc/plugin/policy/admission-control/src/config.rs new file mode 100644 index 00000000..11fe557c --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/src/config.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct AdmissionControlConfig {} + +impl AdmissionControlConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/admission-control/src/engine.rs b/experimental/mrpc/plugin/policy/admission-control/src/engine.rs new file mode 100644 index 00000000..4e81ed6e --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/src/engine.rs @@ -0,0 +1,245 @@ +//! This engine can only be placed at the sender side for now. +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap as HashMap; +use futures::future::BoxFuture; +use rand::Rng; +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; +use std::time::Instant; + +use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; +use phoenix_api_policy_admission_control::control_plane; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::AdmissionControlConfig; + +pub mod hello { + // The string specified here must match the proto package name + include!("rpc_hello.rs"); +} + +pub(crate) struct AdmissionControlEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + pub(crate) total: u32, + pub(crate) success: u32, + pub(crate) last_ts: Instant, + pub(crate) config: AdmissionControlConfig, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for AdmissionControlEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "AdmissionControlEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + // Update config + self.config = AdmissionControlConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(AdmissionControlEngine, node); + +impl Decompose for AdmissionControlEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(2); + collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("success".to_string(), Box::new(engine.success as u32)); + collections.insert("total".to_string(), Box::new(engine.total as u32)); + collections.insert("last_ts".to_string(), Box::new(engine.last_ts)); + (collections, engine.node) + } +} + +impl AdmissionControlEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let total = *local + .remove("total") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let success = *local + .remove("success") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let last_ts = *local + .remove("last_ts") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let engine = AdmissionControlEngine { + node, + indicator: Default::default(), + total, + success, + last_ts, + config, + }; + Ok(engine) + } +} + +impl AdmissionControlEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +#[inline] +fn calculate_reject_probability(total: u32, succ: u32, threhold: u32, agg: f32) -> f32 { + let s: f32 = succ as f32 / threhold as f32; + let u = (total as f32 - s) / (total as f32 + 1.0); + u.powf(1.0 / agg) +} + +impl AdmissionControlEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let conn_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.call_id; + let rpc_id = RpcId { + 0: conn_id, + 1: call_id, + }; + if rand::random::() + < calculate_reject_probability( + self.total as u32, + self.success as u32, + 10, + 0.5, + ) + { + let error = EngineRxMessage::Ack( + rpc_id, + TransportStatus::Error(unsafe { NonZeroU32::new_unchecked(403) }), + ); + self.rx_outputs()[0].send(error).unwrap_or_else(|e| { + log::warn!("error when bubbling up the error, send failed e: {}", e) + }); + } else { + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + } + // XXX TODO(cjr): it is best not to reorder the message + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + // forward all rx msgs + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + match m { + EngineRxMessage::RpcMessage(msg) => { + let meta = unsafe { &*msg.meta.as_ptr() }; + if meta.status_code == StatusCode::Success { + self.success += 1; + } + self.total += 1; + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => { + self.rx_outputs()[0].send(m)?; + } + }; + if std::time::Instant::now() - self.last_ts > std::time::Duration::from_secs(5) { + self.last_ts = std::time::Instant::now(); + self.total = 0; + self.success = 0; + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/admission-control/src/lib.rs b/experimental/mrpc/plugin/policy/admission-control/src/lib.rs new file mode 100644 index 00000000..dc7af5a9 --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/src/lib.rs @@ -0,0 +1,34 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::AdmissionControlConfig; +use crate::module::AdmissionControlAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = AdmissionControlConfig::new(config_string)?; + let addon = AdmissionControlAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/admission-control/src/module.rs b/experimental/mrpc/plugin/policy/admission-control/src/module.rs new file mode 100644 index 00000000..1afc5ce7 --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/src/module.rs @@ -0,0 +1,103 @@ +use anyhow::{bail, Result}; +use fnv::FnvHashMap as HashMap; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::AdmissionControlEngine; +use crate::config::AdmissionControlConfig; + +pub(crate) struct AdmissionControlEngineBuilder { + node: DataPathNode, + config: AdmissionControlConfig, +} + +impl AdmissionControlEngineBuilder { + fn new(node: DataPathNode, config: AdmissionControlConfig) -> Self { + AdmissionControlEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(AdmissionControlEngine { + node: self.node, + indicator: Default::default(), + total: 0, + success: 0, + last_ts: std::time::Instant::now(), + config: self.config, + }) + } +} + +pub struct AdmissionControlAddon { + config: AdmissionControlConfig, +} + +impl AdmissionControlAddon { + pub const ADMISSION_CONTROL_ENGINE: EngineType = EngineType("AdmissionControlEngine"); + pub const ENGINES: &'static [EngineType] = &[AdmissionControlAddon::ADMISSION_CONTROL_ENGINE]; +} + +impl AdmissionControlAddon { + pub fn new(config: AdmissionControlConfig) -> Self { + AdmissionControlAddon { config } + } +} + +impl PhoenixAddon for AdmissionControlAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + AdmissionControlAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != AdmissionControlAddon::ADMISSION_CONTROL_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = AdmissionControlEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != AdmissionControlAddon::ADMISSION_CONTROL_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = AdmissionControlEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/admission-control/src/rpc_hello.rs b/experimental/mrpc/plugin/policy/admission-control/src/rpc_hello.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/admission-control/src/rpc_hello.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } From 9ac96d80a513b8064b644a4c647ff443e6242420 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 23 Oct 2023 21:22:44 -0400 Subject: [PATCH 09/21] finish admisson control --- experimental/mrpc/load-mrpc-plugins.toml | 2 -- .../mrpc/phoenix-api/policy/metrics/Cargo.toml | 11 +++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 experimental/mrpc/phoenix-api/policy/metrics/Cargo.toml diff --git a/experimental/mrpc/load-mrpc-plugins.toml b/experimental/mrpc/load-mrpc-plugins.toml index 2a929dc5..a351a952 100644 --- a/experimental/mrpc/load-mrpc-plugins.toml +++ b/experimental/mrpc/load-mrpc-plugins.toml @@ -98,5 +98,3 @@ name = "Mutation" lib_path = "plugins/libphoenix_mutation.rlib" config_string = ''' ''' - -[[addons]] diff --git a/experimental/mrpc/phoenix-api/policy/metrics/Cargo.toml b/experimental/mrpc/phoenix-api/policy/metrics/Cargo.toml new file mode 100644 index 00000000..b7d3bbbb --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-metrics" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true From 536918e0e5fa2ccf64b56820dc9b16b1c84bd390 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 23 Oct 2023 22:11:04 -0400 Subject: [PATCH 10/21] metrics --- experimental/mrpc/Cargo.lock | 4 +- .../policy/metrics/src/control_plane.rs | 14 ++ .../phoenix-api/policy/metrics/src/lib.rs | 1 + .../phoenix-api/policy/mutation/Cargo.toml | 11 + .../mrpc/plugin/policy/metrics/Cargo.toml | 27 +++ .../mrpc/plugin/policy/metrics/src/config.rs | 12 ++ .../mrpc/plugin/policy/metrics/src/engine.rs | 191 ++++++++++++++++++ .../mrpc/plugin/policy/metrics/src/lib.rs | 34 ++++ .../mrpc/plugin/policy/metrics/src/module.rs | 102 ++++++++++ 9 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 experimental/mrpc/phoenix-api/policy/metrics/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/metrics/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/mutation/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/metrics/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/metrics/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/metrics/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/metrics/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/metrics/src/module.rs diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index da65e132..21177440 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1909,7 +1909,7 @@ dependencies = [ "mrpc-marshal", "nix", "phoenix-api", - "phoenix-api-policy-hello-acl-sender", + "phoenix-api-policy-metrics", "phoenix_common", "serde", "serde_json", @@ -1995,7 +1995,7 @@ dependencies = [ "mrpc-marshal", "nix", "phoenix-api", - "phoenix-api-policy-hello-acl-sender", + "phoenix-api-policy-mutation", "phoenix_common", "serde", "serde_json", diff --git a/experimental/mrpc/phoenix-api/policy/metrics/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/metrics/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/metrics/src/lib.rs b/experimental/mrpc/phoenix-api/policy/metrics/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/mutation/Cargo.toml b/experimental/mrpc/phoenix-api/policy/mutation/Cargo.toml new file mode 100644 index 00000000..b17eaabd --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-mutation" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/plugin/policy/metrics/Cargo.toml b/experimental/mrpc/plugin/policy/metrics/Cargo.toml new file mode 100644 index 00000000..b5118932 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "phoenix-metrics" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +phoenix-api-policy-metrics.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true + +phoenix_common.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +fnv.workspace = true diff --git a/experimental/mrpc/plugin/policy/metrics/src/config.rs b/experimental/mrpc/plugin/policy/metrics/src/config.rs new file mode 100644 index 00000000..d50cca93 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics/src/config.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MetricsConfig {} + +impl MetricsConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/metrics/src/engine.rs b/experimental/mrpc/plugin/policy/metrics/src/engine.rs new file mode 100644 index 00000000..4cf93363 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics/src/engine.rs @@ -0,0 +1,191 @@ +//! This engine can only be placed at the sender side for now. +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; + +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap as HashMap; +use futures::future::BoxFuture; + +use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; +use phoenix_api_policy_metrics::control_plane; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::MetricsConfig; + +pub(crate) struct MetricsEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + pub(crate) num_succ: u32, + pub(crate) num_rej: u32, + + pub(crate) config: MetricsConfig, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for MetricsEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "MetricsEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + // Update config + self.config = MetricsConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(MetricsEngine, node); + +impl Decompose for MetricsEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(2); + collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("num_rej".to_string(), Box::new(engine.num_rej)); + collections.insert("num_succ".to_string(), Box::new(engine.num_succ)); + (collections, engine.node) + } +} + +impl MetricsEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_succ = *local + .remove("num_succ") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_rej = *local + .remove("num_rej") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let engine = MetricsEngine { + node, + indicator: Default::default(), + num_succ, + num_rej, + config, + }; + Ok(engine) + } +} + +impl MetricsEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +impl MetricsEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + self.tx_outputs()[0].send(msg)?; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + // forward all rx msgs + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + match m { + EngineRxMessage::RpcMessage(msg) => { + let meta = unsafe { &*msg.meta.as_ptr() }; + if meta.status_code == StatusCode::Success { + self.num_succ += 1; + } else { + self.num_rej += 1; + } + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => { + self.rx_outputs()[0].send(m)?; + } + }; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/metrics/src/lib.rs b/experimental/mrpc/plugin/policy/metrics/src/lib.rs new file mode 100644 index 00000000..0f40afdf --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics/src/lib.rs @@ -0,0 +1,34 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::MetricsConfig; +use crate::module::MetricsAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = MetricsConfig::new(config_string)?; + let addon = MetricsAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/metrics/src/module.rs b/experimental/mrpc/plugin/policy/metrics/src/module.rs new file mode 100644 index 00000000..9aaef7a2 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics/src/module.rs @@ -0,0 +1,102 @@ +use anyhow::{bail, Result}; +use fnv::FnvHashMap as HashMap; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::MetricsEngine; +use crate::config::MetricsConfig; + +pub(crate) struct MetricsEngineBuilder { + node: DataPathNode, + config: MetricsConfig, +} + +impl MetricsEngineBuilder { + fn new(node: DataPathNode, config: MetricsConfig) -> Self { + MetricsEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(MetricsEngine { + node: self.node, + indicator: Default::default(), + num_succ: 0, + num_rej: 0, + config: self.config, + }) + } +} + +pub struct MetricsAddon { + config: MetricsConfig, +} + +impl MetricsAddon { + pub const METRICS_ENGINE: EngineType = EngineType("MetricsEngine"); + pub const ENGINES: &'static [EngineType] = &[MetricsAddon::METRICS_ENGINE]; +} + +impl MetricsAddon { + pub fn new(config: MetricsConfig) -> Self { + MetricsAddon { config } + } +} + +impl PhoenixAddon for MetricsAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + MetricsAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != MetricsAddon::METRICS_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = MetricsEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != MetricsAddon::METRICS_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = MetricsEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} From 1968ae997cd0edbaef43de3d7331ff1ebb9403dd Mon Sep 17 00:00:00 2001 From: banruo Date: Tue, 24 Oct 2023 03:59:48 -0400 Subject: [PATCH 11/21] mutation --- eval/policy/mutation/attach.toml | 31 +++ eval/policy/mutation/detach.toml | 6 + .../policy/mutation/src/control_plane.rs | 14 ++ .../phoenix-api/policy/mutation/src/lib.rs | 1 + .../mrpc/plugin/policy/mutation/Cargo.toml | 27 +++ .../mrpc/plugin/policy/mutation/src/config.rs | 12 ++ .../mrpc/plugin/policy/mutation/src/engine.rs | 195 ++++++++++++++++++ .../mrpc/plugin/policy/mutation/src/lib.rs | 34 +++ .../mrpc/plugin/policy/mutation/src/module.rs | 101 +++++++++ .../plugin/policy/mutation/src/rpc_hello.rs | 29 +++ 10 files changed, 450 insertions(+) create mode 100644 eval/policy/mutation/attach.toml create mode 100644 eval/policy/mutation/detach.toml create mode 100644 experimental/mrpc/phoenix-api/policy/mutation/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/mutation/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/mutation/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/mutation/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/mutation/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/mutation/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/mutation/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/mutation/src/rpc_hello.rs diff --git a/eval/policy/mutation/attach.toml b/eval/policy/mutation/attach.toml new file mode 100644 index 00000000..b739a2e2 --- /dev/null +++ b/eval/policy/mutation/attach.toml @@ -0,0 +1,31 @@ +addon_engine = "MutationEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "MutationEngine", + 0, + 0, + ], + [ + "MutationEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "MutationEngine", + 0, + 0, + ], + [ + "MutationEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" diff --git a/eval/policy/mutation/detach.toml b/eval/policy/mutation/detach.toml new file mode 100644 index 00000000..465cc3e0 --- /dev/null +++ b/eval/policy/mutation/detach.toml @@ -0,0 +1,6 @@ +addon_engine = "LoggingEngine" +tx_channels_replacements = [ + ["MrpcEngine", "RpcAdapterEngine", 0, 0], +] +rx_channels_replacements = [] +op = "detach" diff --git a/experimental/mrpc/phoenix-api/policy/mutation/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/mutation/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/mutation/src/lib.rs b/experimental/mrpc/phoenix-api/policy/mutation/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/plugin/policy/mutation/Cargo.toml b/experimental/mrpc/plugin/policy/mutation/Cargo.toml new file mode 100644 index 00000000..da4953c0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "phoenix-mutation" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +phoenix-api-policy-mutation.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true + +phoenix_common.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +fnv.workspace = true diff --git a/experimental/mrpc/plugin/policy/mutation/src/config.rs b/experimental/mrpc/plugin/policy/mutation/src/config.rs new file mode 100644 index 00000000..ab1d2d5f --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/src/config.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MutationConfig {} + +impl MutationConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation/src/engine.rs b/experimental/mrpc/plugin/policy/mutation/src/engine.rs new file mode 100644 index 00000000..ffb4d958 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/src/engine.rs @@ -0,0 +1,195 @@ +//! This engine can only be placed at the sender side for now. +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; + +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap as HashMap; +use futures::future::BoxFuture; + +use phoenix_api::rpc::{RpcId, TransportStatus}; +use phoenix_api_policy_mutation::control_plane; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::MutationConfig; + +pub(crate) struct MutationEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + pub(crate) config: MutationConfig, + + pub(crate) target: String, +} + +pub mod hello { + // The string specified here must match the proto package name + include!("rpc_hello.rs"); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for MutationEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "MutationEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + // Update config + self.config = MutationConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(MutationEngine, node); + +impl Decompose for MutationEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(2); + collections.insert("target".to_string(), Box::new(engine.target)); + collections.insert("config".to_string(), Box::new(engine.config)); + (collections, engine.node) + } +} + +impl MutationEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let target = *local + .remove("target") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let engine = MutationEngine { + node, + indicator: Default::default(), + target, + config, + }; + Ok(engine) + } +} + +impl MutationEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +/// Copy the RPC request to a private heap and returns the request. +#[inline] +fn materialize(msg: &RpcMessageTx) -> Box { + let req_ptr = Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_ref() }; + // returns a private_req + Box::new(req.clone()) +} + +impl MutationEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let mut req_ptr = + Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_mut() }; + for i in 0..req.name.len() { + req.name[i] = 'a' as u8; + } + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + // forward all rx msgs + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + self.rx_outputs()[0].send(m)?; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation/src/lib.rs b/experimental/mrpc/plugin/policy/mutation/src/lib.rs new file mode 100644 index 00000000..04a1a081 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/src/lib.rs @@ -0,0 +1,34 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::MutationConfig; +use crate::module::MutationAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = MutationConfig::new(config_string)?; + let addon = MutationAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/mutation/src/module.rs b/experimental/mrpc/plugin/policy/mutation/src/module.rs new file mode 100644 index 00000000..f7b47bca --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/src/module.rs @@ -0,0 +1,101 @@ +use anyhow::{bail, Result}; +use fnv::FnvHashMap as HashMap; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::MutationEngine; +use crate::config::MutationConfig; + +pub(crate) struct MutationEngineBuilder { + node: DataPathNode, + config: MutationConfig, +} + +impl MutationEngineBuilder { + fn new(node: DataPathNode, config: MutationConfig) -> Self { + MutationEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(MutationEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + target: "Banana".to_string(), + }) + } +} + +pub struct MutationAddon { + config: MutationConfig, +} + +impl MutationAddon { + pub const MUTATION_ENGINE: EngineType = EngineType("MutationEngine"); + pub const ENGINES: &'static [EngineType] = &[MutationAddon::MUTATION_ENGINE]; +} + +impl MutationAddon { + pub fn new(config: MutationConfig) -> Self { + MutationAddon { config } + } +} + +impl PhoenixAddon for MutationAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + MutationAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != MutationAddon::MUTATION_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = MutationEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != MutationAddon::MUTATION_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = MutationEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation/src/rpc_hello.rs b/experimental/mrpc/plugin/policy/mutation/src/rpc_hello.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation/src/rpc_hello.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } From de1c0845ddc91b9fd663963f81a5c14810f03d76 Mon Sep 17 00:00:00 2001 From: banruo Date: Tue, 24 Oct 2023 05:45:23 -0400 Subject: [PATCH 12/21] update --- experimental/mrpc/Cargo.lock | 1230 +++++++++++++++++++--------------- 1 file changed, 683 insertions(+), 547 deletions(-) diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index e6ac5fcd..07bf968f 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -10,24 +19,30 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.10", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -48,44 +63,44 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arc-swap" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-channel" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] [[package]] name = "async-executor" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" dependencies = [ + "async-lock", "async-task", "concurrent-queue", - "fastrand", + "fastrand 2.0.1", "futures-lite", - "once_cell", "slab", ] @@ -103,78 +118,94 @@ dependencies = [ [[package]] name = "async-io" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ + "async-lock", "autocfg", + "cfg-if 1.0.0", "concurrent-queue", "futures-lite", - "libc", "log", - "once_cell", "parking", "polling", + "rustix 0.37.26", "slab", - "socket2", + "socket2 0.4.10", "waker-fn", - "winapi 0.3.9", ] [[package]] name = "async-lock" -version = "2.5.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] name = "async-net" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" dependencies = [ "async-io", - "autocfg", "blocking", "futures-lite", ] [[package]] name = "async-process" -version = "1.5.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02111fd8655a613c25069ea89fc8d9bb89331fa77486eb3bc059ee757cfa481c" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ "async-io", - "autocfg", + "async-lock", + "async-signal", "blocking", "cfg-if 1.0.0", - "event-listener", + "event-listener 3.0.0", "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi 0.3.9", + "rustix 0.38.20", + "windows-sys", +] + +[[package]] +name = "async-signal" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix 0.38.20", + "signal-hook-registry", + "slab", + "windows-sys", ] [[package]] name = "async-task" -version = "4.3.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" +checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] @@ -189,9 +220,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atty" @@ -199,7 +230,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi 0.3.9", ] @@ -210,6 +241,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -260,6 +306,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitvec" version = "1.0.1" @@ -274,47 +326,46 @@ dependencies = [ [[package]] name = "blocking" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" dependencies = [ "async-channel", + "async-lock", "async-task", - "atomic-waker", - "fastrand", + "fastrand 2.0.1", + "futures-io", "futures-lite", - "once_cell", + "piper", + "tracing", ] [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cache-padded" -version = "1.2.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cexpr" @@ -339,24 +390,23 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", - "time 0.1.44", "wasm-bindgen", - "winapi 0.3.9", + "windows-targets", ] [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -381,37 +431,27 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.48" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" dependencies = [ "cc", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "concurrent-queue" -version = "1.2.4" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ - "cache-padded", + "crossbeam-utils 0.8.16", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "crc32fast" @@ -429,11 +469,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ "cfg-if 1.0.0", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-deque", "crossbeam-epoch", "crossbeam-queue", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", ] [[package]] @@ -448,46 +488,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", ] [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", - "memoffset 0.8.0", + "crossbeam-utils 0.8.16", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", ] [[package]] @@ -503,9 +543,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", ] @@ -517,77 +557,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", -] - -[[package]] -name = "cxx" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", + "syn 1.0.109", ] [[package]] -name = "cxx-build" -version = "1.0.80" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cc", - "codespan-reporting", + "cfg-if 1.0.0", + "hashbrown 0.14.2", + "lock_api", "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "parking_lot_core", ] [[package]] -name = "dashmap" -version = "5.4.0" +name = "deranged" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ - "cfg-if 1.0.0", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_core", + "powerfmt", ] [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -596,6 +601,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.1.8" @@ -609,30 +620,30 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", - "winapi 0.3.9", + "windows-sys", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "2.5.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "fasthash" @@ -658,13 +669,19 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -673,9 +690,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -717,9 +734,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -732,9 +749,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -742,15 +759,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -760,17 +777,17 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -781,32 +798,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -839,9 +856,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -850,11 +867,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" @@ -865,6 +888,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + [[package]] name = "hdrhistogram" version = "7.5.2" @@ -873,7 +902,7 @@ checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" dependencies = [ "base64", "byteorder", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "flate2", "nom", "num-traits", @@ -890,9 +919,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -903,11 +932,26 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "hotel_reservation" version = "0.1.0" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures", "hdrhistogram", "minstant", @@ -926,36 +970,45 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.51" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi 0.3.9", + "windows-core", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", ] [[package]] @@ -967,6 +1020,17 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.3", + "libc", + "windows-sys", +] + [[package]] name = "iovec" version = "0.1.4" @@ -987,9 +1051,9 @@ dependencies = [ "ipc-channel", "libc", "memfd", - "memmap2 0.5.7", + "memmap2 0.5.10", "minstant", - "mio 0.8.5", + "mio 0.8.9", "nix", "phoenix-api", "serde", @@ -1029,15 +1093,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1077,15 +1141,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.136" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55edcf6c0bb319052dea84732cf99db461780fd5e8d3eb46ab6ff312ab31f197" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", @@ -1115,18 +1179,30 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1134,12 +1210,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "masstree_analytics" @@ -1148,10 +1221,10 @@ dependencies = [ "arc-swap", "chrono", "cmake", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", "env_logger", "fasthash", - "fastrand", + "fastrand 1.9.0", "futures", "link-cplusplus", "log", @@ -1170,7 +1243,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1187,9 +1260,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memfd" @@ -1211,9 +1284,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -1229,9 +1302,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -1244,18 +1317,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "minstant" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5dcfca9a0725105ac948b84cfeb69c3942814c696326743797215413f854b9" +checksum = "b8dfc09c8abbe145769b6d51fd03f84fdd459906cbd6ac54e438708f016b40bd" dependencies = [ "ctor", "libc", @@ -1296,9 +1369,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "log", @@ -1376,7 +1449,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1387,7 +1460,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "thiserror", ] @@ -1409,9 +1482,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "net2" -version = "0.2.38" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ "cfg-if 0.1.10", "libc", @@ -1420,9 +1493,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", "bitflags 1.3.2", @@ -1434,9 +1507,9 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -1461,49 +1534,39 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] [[package]] -name = "num_threads" -version = "0.1.6" +name = "object" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "overload" @@ -1523,9 +1586,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -1539,15 +1602,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] @@ -1558,22 +1621,23 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pest" -version = "2.4.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" +checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.0.2", ] [[package]] @@ -1725,6 +1789,22 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-metrics" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + +[[package]] +name = "phoenix-api-policy-mutation" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-nofile-logging" version = "0.1.0" @@ -1806,15 +1886,15 @@ name = "phoenix-common-workspace" version = "0.1.0" dependencies = [ "ahash", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.16", "futures-core", - "getrandom 0.2.8", - "hashbrown", + "getrandom 0.2.10", + "hashbrown 0.12.3", "ipc", "log", - "mio 0.8.5", + "mio 0.8.9", "once_cell", "phoenix-api", "tokio", @@ -1990,7 +2070,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand", + "fastrand 1.9.0", "fnv", "futures", "ipc", @@ -2006,7 +2086,7 @@ dependencies = [ "phoenix_common", "serde", "slab", - "socket2", + "socket2 0.4.10", "spin", "thiserror", "tokio", @@ -2038,13 +2118,35 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-metrics" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-metrics", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-mrpc" version = "0.1.0" dependencies = [ "anyhow", "crc32fast", - "fastrand", + "fastrand 1.9.0", "fnv", "futures", "ipc", @@ -2062,7 +2164,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "syn", + "syn 1.0.109", "thiserror", "tokio", "toml", @@ -2076,7 +2178,7 @@ version = "0.1.0" dependencies = [ "anyhow", "crc32fast", - "fastrand", + "fastrand 1.9.0", "fnv", "futures", "ipc", @@ -2094,7 +2196,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "syn", + "syn 1.0.109", "thiserror", "tokio", "toml", @@ -2229,7 +2331,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand", + "fastrand 1.9.0", "fnv", "futures", "ipc", @@ -2282,7 +2384,7 @@ dependencies = [ "lazy_static", "libc", "memfd", - "memmap2 0.5.7", + "memmap2 0.5.10", "phoenix-api", "serde_json", "spin", @@ -2299,7 +2401,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand", + "fastrand 1.9.0", "fnv", "futures", "ipc", @@ -2315,7 +2417,7 @@ dependencies = [ "phoenix_common", "serde", "slab", - "socket2", + "socket2 0.4.10", "spin", "thiserror", "tokio", @@ -2357,12 +2459,12 @@ dependencies = [ "ipc", "lazy_static", "memoffset 0.6.5", - "mio 0.8.5", + "mio 0.8.9", "nix", "phoenix-api", "phoenix_common", "serde", - "socket2", + "socket2 0.4.10", "spin", "thiserror", "tokio", @@ -2386,7 +2488,7 @@ dependencies = [ "phoenix-api", "phoenix-api-mrpc", "phoenix-common-workspace", - "semver 1.0.14", + "semver 1.0.20", "sharded-slab", "static_assertions", "thiserror", @@ -2396,9 +2498,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2406,34 +2508,53 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "polling" -version = "2.4.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg", + "bitflags 1.3.2", "cfg-if 1.0.0", + "concurrent-queue", "libc", "log", - "wepoll-ffi", - "winapi 0.3.9", + "pin-project-lite", + "windows-sys", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.1.21" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -2445,7 +2566,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -2462,9 +2583,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -2485,7 +2606,7 @@ dependencies = [ "bytes", "cfg-if 1.0.0", "cmake", - "heck 0.4.0", + "heck 0.4.1", "itertools", "lazy_static", "log", @@ -2506,7 +2627,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2519,9 +2640,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2554,7 +2675,6 @@ dependencies = [ "getrandom 0.1.16", "libc", "rand_chacha 0.2.2", - "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc", ] @@ -2570,17 +2690,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.2.2" @@ -2601,16 +2710,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_core" version = "0.3.1" @@ -2641,16 +2740,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.10", ] [[package]] @@ -2677,7 +2767,7 @@ dependencies = [ "nix", "phoenix-api", "serde", - "socket2", + "socket2 0.4.10", "spin", "static_assertions", "thiserror", @@ -2694,22 +2784,32 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.6.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -2718,23 +2818,31 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", ] [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "regex-syntax" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi 0.3.9", -] +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rpc_bench" @@ -2783,6 +2891,12 @@ dependencies = [ "structopt", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2798,11 +2912,38 @@ dependencies = [ "semver 0.11.0", ] +[[package]] +name = "rustix" +version = "0.37.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" +dependencies = [ + "bitflags 1.3.2", + "errno 0.3.5", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +dependencies = [ + "bitflags 2.4.1", + "errno 0.3.5", + "libc", + "linux-raw-sys 0.4.10", + "windows-sys", +] + [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scheduler" @@ -2810,21 +2951,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fa43f074ab0432dea0abfafb02b211ff81fb4119617d1c9148a5e7b9c372038" dependencies = [ - "errno 0.2.8", + "errno 0.3.5", "libc", ] [[package]] name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scratch" -version = "1.0.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -2843,9 +2978,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "semver-parser" @@ -2858,29 +2993,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -2889,18 +3024,18 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] [[package]] name = "shlex" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "shm" @@ -2946,30 +3081,20 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "signal-hook" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -2986,15 +3111,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smol" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cf3b5351f3e783c1d79ab5fc604eeed8b8ae9abd36b166e8b87a089efd85e4" +checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" dependencies = [ "async-channel", "async-executor", @@ -3005,24 +3130,33 @@ dependencies = [ "async-process", "blocking", "futures-lite", - "once_cell", ] [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spin" -version = "0.9.4" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] @@ -3060,14 +3194,25 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "syn" -version = "1.0.103" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -3082,7 +3227,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "unicode-xid", ] @@ -3094,23 +3239,22 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if 1.0.0", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi 0.3.9", + "fastrand 2.0.1", + "redox_syscall 0.3.5", + "rustix 0.38.20", + "windows-sys", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] @@ -3126,53 +3270,43 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] [[package]] name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.3.16" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ + "deranged", "itoa", - "libc", - "num_threads", + "powerfmt", "serde", "time-core", "time-macros", @@ -3180,67 +3314,65 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.5" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] [[package]] name = "tokio" -version = "1.21.2" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", - "mio 0.8.5", + "mio 0.8.9", "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.5", "tokio-macros", - "winapi 0.3.9", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "indexmap", + "indexmap 1.9.3", "serde", ] [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3252,27 +3384,27 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ - "crossbeam-channel 0.5.6", - "time 0.3.16", + "crossbeam-channel 0.5.8", + "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -3280,20 +3412,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -3309,27 +3441,27 @@ dependencies = [ [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -3357,7 +3489,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.10", ] [[package]] @@ -3380,9 +3512,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "wasi" @@ -3396,12 +3528,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3410,9 +3536,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3420,24 +3546,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.38", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3445,41 +3571,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "which" -version = "4.3.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix 0.38.20", ] [[package]] @@ -3512,9 +3630,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi 0.3.9", ] @@ -3525,11 +3643,29 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -3542,45 +3678,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "ws2_32-sys" @@ -3594,9 +3730,9 @@ dependencies = [ [[package]] name = "wyz" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] @@ -3633,6 +3769,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d498dbd1fd7beb83c86709ae1c33ca50942889473473d287d56ce4770a18edfb" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.109", "synstructure", ] From f3e5c43a574af1f404523bf6f69d1f4bd1e31098 Mon Sep 17 00:00:00 2001 From: banruo Date: Wed, 25 Oct 2023 08:02:43 -0400 Subject: [PATCH 13/21] fix version --- experimental/mrpc/Cargo.lock | 1161 +++++++++++++++------------------- 1 file changed, 516 insertions(+), 645 deletions(-) diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 07bf968f..4fc7c88c 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" @@ -19,30 +10,24 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.8", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -63,44 +48,44 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-channel" -version = "1.9.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" dependencies = [ "concurrent-queue", - "event-listener 2.5.3", + "event-listener", "futures-core", ] [[package]] name = "async-executor" -version = "1.6.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" dependencies = [ - "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", + "fastrand", "futures-lite", + "once_cell", "slab", ] @@ -118,94 +103,78 @@ dependencies = [ [[package]] name = "async-io" -version = "1.13.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7" dependencies = [ - "async-lock", "autocfg", - "cfg-if 1.0.0", "concurrent-queue", "futures-lite", + "libc", "log", + "once_cell", "parking", "polling", - "rustix 0.37.26", "slab", - "socket2 0.4.10", + "socket2", "waker-fn", + "winapi 0.3.9", ] [[package]] name = "async-lock" -version = "2.8.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" dependencies = [ - "event-listener 2.5.3", + "event-listener", ] [[package]] name = "async-net" -version = "1.8.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" +checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" dependencies = [ "async-io", + "autocfg", "blocking", "futures-lite", ] [[package]] name = "async-process" -version = "1.8.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "02111fd8655a613c25069ea89fc8d9bb89331fa77486eb3bc059ee757cfa481c" dependencies = [ "async-io", - "async-lock", - "async-signal", + "autocfg", "blocking", "cfg-if 1.0.0", - "event-listener 3.0.0", + "event-listener", "futures-lite", - "rustix 0.38.20", - "windows-sys", -] - -[[package]] -name = "async-signal" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix 0.38.20", - "signal-hook-registry", - "slab", - "windows-sys", + "libc", + "once_cell", + "signal-hook", + "winapi 0.3.9", ] [[package]] name = "async-task" -version = "4.5.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -220,9 +189,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.1.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" [[package]] name = "atty" @@ -230,7 +199,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi 0.3.9", ] @@ -241,21 +210,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.13.1" @@ -306,12 +260,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - [[package]] name = "bitvec" version = "1.0.1" @@ -326,46 +274,47 @@ dependencies = [ [[package]] name = "blocking" -version = "1.4.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" dependencies = [ "async-channel", - "async-lock", "async-task", - "fastrand 2.0.1", - "futures-io", + "atomic-waker", + "fastrand", "futures-lite", - "piper", - "tracing", + "once_cell", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "cache-padded" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cexpr" @@ -390,23 +339,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", + "num-integer", "num-traits", + "time 0.1.44", "wasm-bindgen", - "windows-targets", + "winapi 0.3.9", ] [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", @@ -431,27 +381,37 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.50" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" dependencies = [ "cc", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" dependencies = [ - "crossbeam-utils 0.8.16", + "cache-padded", ] [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "crc32fast" @@ -469,11 +429,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ "cfg-if 1.0.0", - "crossbeam-channel 0.5.8", + "crossbeam-channel 0.5.6", "crossbeam-deque", "crossbeam-epoch", "crossbeam-queue", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", ] [[package]] @@ -488,46 +448,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", - "memoffset 0.9.0", + "crossbeam-utils 0.8.12", + "memoffset 0.8.0", "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", ] [[package]] @@ -543,9 +503,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if 1.0.0", ] @@ -557,42 +517,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn 1.0.109", + "syn", ] [[package]] -name = "dashmap" -version = "5.5.3" +name = "cxx" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.14.2", - "lock_api", + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +dependencies = [ + "cc", + "codespan-reporting", "once_cell", - "parking_lot_core", + "proc-macro2", + "quote", + "scratch", + "syn", ] [[package]] -name = "deranged" -version = "0.3.9" +name = "cxxbridge-flags" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ - "powerfmt", + "cfg-if 1.0.0", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "either" -version = "1.9.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "env_logger" -version = "0.9.3" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" dependencies = [ "atty", "humantime", @@ -601,12 +596,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - [[package]] name = "errno" version = "0.1.8" @@ -620,30 +609,30 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" dependencies = [ + "errno-dragonfly", "libc", - "windows-sys", + "winapi 0.3.9", ] [[package]] -name = "event-listener" -version = "2.5.3" +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] [[package]] name = "event-listener" -version = "3.0.0" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fasthash" @@ -669,19 +658,13 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - [[package]] name = "fixedbitset" version = "0.4.2" @@ -690,9 +673,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", "miniz_oxide", @@ -734,9 +717,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -749,9 +732,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -759,15 +742,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -777,17 +760,17 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-lite" -version = "1.13.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" dependencies = [ - "fastrand 1.9.0", + "fastrand", "futures-core", "futures-io", "memchr", @@ -798,32 +781,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -856,9 +839,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -867,17 +850,11 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" - [[package]] name = "glob" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hashbrown" @@ -888,12 +865,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hashbrown" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" - [[package]] name = "hdrhistogram" version = "7.5.2" @@ -902,7 +873,7 @@ checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" dependencies = [ "base64", "byteorder", - "crossbeam-channel 0.5.8", + "crossbeam-channel 0.5.6", "flate2", "nom", "num-traits", @@ -919,9 +890,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -932,26 +903,11 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys", -] - [[package]] name = "hotel_reservation" version = "0.1.0" dependencies = [ - "fastrand 1.9.0", + "fastrand", "futures", "hdrhistogram", "minstant", @@ -970,45 +926,36 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "winapi 0.3.9", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" dependencies = [ - "cc", + "cxx", + "cxx-build", ] [[package]] name = "indexmap" -version = "1.9.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" -dependencies = [ - "equivalent", - "hashbrown 0.14.2", + "hashbrown", ] [[package]] @@ -1020,17 +967,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.3", - "libc", - "windows-sys", -] - [[package]] name = "iovec" version = "0.1.4" @@ -1051,9 +987,9 @@ dependencies = [ "ipc-channel", "libc", "memfd", - "memmap2 0.5.10", + "memmap2 0.5.7", "minstant", - "mio 0.8.9", + "mio 0.8.5", "nix", "phoenix-api", "serde", @@ -1093,15 +1029,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -1141,15 +1077,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "55edcf6c0bb319052dea84732cf99db461780fd5e8d3eb46ab6ff312ab31f197" [[package]] name = "libloading" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", @@ -1179,30 +1115,18 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.9" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" dependencies = [ "cc", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" - [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1210,9 +1134,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if 1.0.0", +] [[package]] name = "masstree_analytics" @@ -1221,10 +1148,10 @@ dependencies = [ "arc-swap", "chrono", "cmake", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", "env_logger", "fasthash", - "fastrand 1.9.0", + "fastrand", "futures", "link-cplusplus", "log", @@ -1243,7 +1170,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -1260,9 +1187,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.6.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memfd" @@ -1284,9 +1211,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.5.10" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" dependencies = [ "libc", ] @@ -1302,9 +1229,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -1317,18 +1244,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] [[package]] name = "minstant" -version = "0.1.4" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dfc09c8abbe145769b6d51fd03f84fdd459906cbd6ac54e438708f016b40bd" +checksum = "bc5dcfca9a0725105ac948b84cfeb69c3942814c696326743797215413f854b9" dependencies = [ "ctor", "libc", @@ -1369,9 +1296,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", @@ -1449,7 +1376,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1460,7 +1387,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "thiserror", ] @@ -1482,9 +1409,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "net2" -version = "0.2.39" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" +checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" dependencies = [ "cfg-if 0.1.10", "libc", @@ -1493,9 +1420,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" dependencies = [ "autocfg", "bitflags 1.3.2", @@ -1507,9 +1434,9 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.3" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", @@ -1534,39 +1461,49 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "libc", ] [[package]] -name = "object" -version = "0.32.1" +name = "num_threads" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ - "memchr", + "libc", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "overload" @@ -1586,9 +1523,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] name = "parking_lot" @@ -1602,15 +1539,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", - "windows-targets", + "windows-sys", ] [[package]] @@ -1621,23 +1558,22 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pest" -version = "2.7.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" +checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" dependencies = [ - "memchr", "thiserror", "ucd-trie", ] [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap", ] [[package]] @@ -1886,15 +1822,15 @@ name = "phoenix-common-workspace" version = "0.1.0" dependencies = [ "ahash", - "crossbeam-channel 0.5.8", + "crossbeam-channel 0.5.6", "crossbeam-epoch", - "crossbeam-utils 0.8.16", + "crossbeam-utils 0.8.12", "futures-core", - "getrandom 0.2.10", - "hashbrown 0.12.3", + "getrandom 0.2.8", + "hashbrown", "ipc", "log", - "mio 0.8.9", + "mio 0.8.5", "once_cell", "phoenix-api", "tokio", @@ -2070,7 +2006,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand 1.9.0", + "fastrand", "fnv", "futures", "ipc", @@ -2086,7 +2022,7 @@ dependencies = [ "phoenix_common", "serde", "slab", - "socket2 0.4.10", + "socket2", "spin", "thiserror", "tokio", @@ -2146,7 +2082,7 @@ version = "0.1.0" dependencies = [ "anyhow", "crc32fast", - "fastrand 1.9.0", + "fastrand", "fnv", "futures", "ipc", @@ -2164,7 +2100,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "syn 1.0.109", + "syn", "thiserror", "tokio", "toml", @@ -2178,7 +2114,7 @@ version = "0.1.0" dependencies = [ "anyhow", "crc32fast", - "fastrand 1.9.0", + "fastrand", "fnv", "futures", "ipc", @@ -2196,7 +2132,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "syn 1.0.109", + "syn", "thiserror", "tokio", "toml", @@ -2331,7 +2267,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand 1.9.0", + "fastrand", "fnv", "futures", "ipc", @@ -2384,7 +2320,7 @@ dependencies = [ "lazy_static", "libc", "memfd", - "memmap2 0.5.10", + "memmap2 0.5.7", "phoenix-api", "serde_json", "spin", @@ -2401,7 +2337,7 @@ dependencies = [ "bincode", "bitvec", "dashmap", - "fastrand 1.9.0", + "fastrand", "fnv", "futures", "ipc", @@ -2417,7 +2353,7 @@ dependencies = [ "phoenix_common", "serde", "slab", - "socket2 0.4.10", + "socket2", "spin", "thiserror", "tokio", @@ -2459,12 +2395,12 @@ dependencies = [ "ipc", "lazy_static", "memoffset 0.6.5", - "mio 0.8.9", + "mio 0.8.5", "nix", "phoenix-api", "phoenix_common", "serde", - "socket2 0.4.10", + "socket2", "spin", "thiserror", "tokio", @@ -2488,7 +2424,7 @@ dependencies = [ "phoenix-api", "phoenix-api-mrpc", "phoenix-common-workspace", - "semver 1.0.20", + "semver 1.0.14", "sharded-slab", "static_assertions", "thiserror", @@ -2498,9 +2434,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -2508,53 +2444,34 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand 2.0.1", - "futures-io", -] - [[package]] name = "polling" -version = "2.8.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2" dependencies = [ "autocfg", - "bitflags 1.3.2", "cfg-if 1.0.0", - "concurrent-queue", "libc", "log", - "pin-project-lite", - "windows-sys", + "wepoll-ffi", + "winapi 0.3.9", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "prettyplease" -version = "0.1.25" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51" dependencies = [ "proc-macro2", - "syn 1.0.109", + "syn", ] [[package]] @@ -2566,7 +2483,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "version_check", ] @@ -2583,9 +2500,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -2606,7 +2523,7 @@ dependencies = [ "bytes", "cfg-if 1.0.0", "cmake", - "heck 0.4.1", + "heck 0.4.0", "itertools", "lazy_static", "log", @@ -2627,7 +2544,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -2640,9 +2557,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -2740,7 +2657,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.8", ] [[package]] @@ -2767,7 +2684,7 @@ dependencies = [ "nix", "phoenix-api", "serde", - "socket2 0.4.10", + "socket2", "spin", "static_assertions", "thiserror", @@ -2784,32 +2701,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -2818,31 +2725,23 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] -name = "regex-syntax" -version = "0.8.2" +name = "remove_dir_all" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] [[package]] name = "rpc_bench" @@ -2891,12 +2790,6 @@ dependencies = [ "structopt", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -2912,38 +2805,11 @@ dependencies = [ "semver 0.11.0", ] -[[package]] -name = "rustix" -version = "0.37.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" -dependencies = [ - "bitflags 1.3.2", - "errno 0.3.5", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", -] - -[[package]] -name = "rustix" -version = "0.38.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" -dependencies = [ - "bitflags 2.4.1", - "errno 0.3.5", - "libc", - "linux-raw-sys 0.4.10", - "windows-sys", -] - [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "scheduler" @@ -2951,15 +2817,21 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fa43f074ab0432dea0abfafb02b211ff81fb4119617d1c9148a5e7b9c372038" dependencies = [ - "errno 0.3.5", + "errno 0.2.8", "libc", ] [[package]] name = "scopeguard" -version = "1.2.0" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "seahash" @@ -2978,9 +2850,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "semver-parser" @@ -2993,29 +2865,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", @@ -3024,18 +2896,18 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.7" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] [[package]] name = "shlex" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "shm" @@ -3081,20 +2953,30 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.9" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ "autocfg", ] @@ -3111,15 +2993,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smol" -version = "1.3.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +checksum = "85cf3b5351f3e783c1d79ab5fc604eeed8b8ae9abd36b166e8b87a089efd85e4" dependencies = [ "async-channel", "async-executor", @@ -3130,33 +3012,24 @@ dependencies = [ "async-process", "blocking", "futures-lite", + "once_cell", ] [[package]] name = "socket2" -version = "0.4.10" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi 0.3.9", ] -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys", -] - [[package]] name = "spin" -version = "0.9.8" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" dependencies = [ "lock_api", ] @@ -3194,25 +3067,14 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "syn", ] [[package]] name = "syn" -version = "2.0.38" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", @@ -3227,7 +3089,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", "unicode-xid", ] @@ -3239,22 +3101,23 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if 1.0.0", - "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.20", - "windows-sys", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.9", ] [[package]] name = "termcolor" -version = "1.3.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ "winapi-util", ] @@ -3270,43 +3133,53 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ - "cfg-if 1.0.0", "once_cell", ] [[package]] name = "time" -version = "0.3.30" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + +[[package]] +name = "time" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca" dependencies = [ - "deranged", "itoa", - "powerfmt", + "libc", + "num_threads", "serde", "time-core", "time-macros", @@ -3314,65 +3187,67 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b" dependencies = [ "time-core", ] [[package]] name = "tokio" -version = "1.33.0" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ - "backtrace", + "autocfg", "bytes", "libc", - "mio 0.8.9", + "memchr", + "mio 0.8.5", "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", - "windows-sys", + "winapi 0.3.9", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "toml" -version = "0.5.11" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ - "indexmap 1.9.3", + "indexmap", "serde", ] [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ + "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3384,27 +3259,27 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ - "crossbeam-channel 0.5.8", - "time", + "crossbeam-channel 0.5.6", + "time 0.3.16", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -3412,20 +3287,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ + "lazy_static", "log", - "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ "matchers", "nu-ansi-term", @@ -3441,27 +3316,27 @@ dependencies = [ [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" @@ -3489,7 +3364,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.8", ] [[package]] @@ -3512,9 +3387,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "wasi" @@ -3528,6 +3403,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3536,9 +3417,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3546,24 +3427,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3571,33 +3452,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] [[package]] name = "which" -version = "4.4.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "home", + "libc", "once_cell", - "rustix 0.38.20", ] [[package]] @@ -3630,9 +3519,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi 0.3.9", ] @@ -3643,29 +3532,11 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -3678,45 +3549,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "ws2_32-sys" @@ -3730,9 +3601,9 @@ dependencies = [ [[package]] name = "wyz" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" dependencies = [ "tap", ] @@ -3769,6 +3640,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d498dbd1fd7beb83c86709ae1c33ca50942889473473d287d56ce4770a18edfb" dependencies = [ "proc-macro2", - "syn 1.0.109", + "syn", "synstructure", ] From e0370c1e9dd2e4133f5d662956a3b7b03b806c35 Mon Sep 17 00:00:00 2001 From: banruo Date: Fri, 1 Dec 2023 10:16:57 +0000 Subject: [PATCH 14/21] server side engines --- experimental/mrpc/Cargo.lock | 42 +++ experimental/mrpc/Cargo.toml | 18 +- experimental/mrpc/load-mrpc-plugins.toml | 32 +++ .../policy/fault-server/Cargo.toml | 14 + .../policy/fault-server/logging/Cargo.toml | 11 + .../fault-server/logging/src/control_plane.rs | 14 + .../policy/fault-server/logging/src/lib.rs | 1 + .../policy/fault-server/src/control_plane.rs | 14 + .../policy/fault-server/src/lib.rs | 1 + .../policy/logging-server/Cargo.toml | 11 + .../logging-server/src/control_plane.rs | 14 + .../policy/logging-server/src/lib.rs | 1 + .../policy/metrics-server/Cargo.toml | 11 + .../metrics-server/src/control_plane.rs | 14 + .../policy/metrics-server/src/lib.rs | 1 + .../policy/mutation-server/Cargo.toml | 11 + .../mutation-server/src/control_plane.rs | 14 + .../policy/mutation-server/src/lib.rs | 1 + .../policy/ratelimit-drop-server/Cargo.toml | 11 + .../src/control_plane.rs | 14 + .../policy/ratelimit-drop-server/src/lib.rs | 1 + .../plugin/policy/fault-server/Cargo.toml | 28 ++ .../plugin/policy/fault-server/src/config.rs | 37 +++ .../plugin/policy/fault-server/src/engine.rs | 238 ++++++++++++++++ .../plugin/policy/fault-server/src/lib.rs | 37 +++ .../plugin/policy/fault-server/src/module.rs | 106 +++++++ .../plugin/policy/fault-server/src/proto.rs | 29 ++ .../plugin/policy/logging-server/Cargo.toml | 27 ++ .../policy/logging-server/src/config.rs | 41 +++ .../policy/logging-server/src/engine.rs | 239 ++++++++++++++++ .../plugin/policy/logging-server/src/lib.rs | 33 +++ .../policy/logging-server/src/module.rs | 105 +++++++ .../plugin/policy/logging-server/src/proto.rs | 29 ++ .../plugin/policy/metrics-server/Cargo.toml | 27 ++ .../policy/metrics-server/src/config.rs | 12 + .../policy/metrics-server/src/engine.rs | 191 +++++++++++++ .../plugin/policy/metrics-server/src/lib.rs | 34 +++ .../policy/metrics-server/src/module.rs | 102 +++++++ .../plugin/policy/mutation-server/Cargo.toml | 27 ++ .../policy/mutation-server/src/config.rs | 12 + .../policy/mutation-server/src/engine.rs | 195 +++++++++++++ .../plugin/policy/mutation-server/src/lib.rs | 34 +++ .../policy/mutation-server/src/module.rs | 101 +++++++ .../policy/mutation-server/src/rpc_hello.rs | 29 ++ .../policy/ratelimit-drop-server/Cargo.toml | 26 ++ .../ratelimit-drop-server/src/config.rs | 24 ++ .../ratelimit-drop-server/src/engine.rs | 260 ++++++++++++++++++ .../policy/ratelimit-drop-server/src/lib.rs | 32 +++ .../ratelimit-drop-server/src/module.rs | 104 +++++++ .../policy/ratelimit-drop-server/src/proto.rs | 29 ++ 50 files changed, 2438 insertions(+), 1 deletion(-) create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/logging/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/logging/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/logging/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/fault-server/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/logging-server/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/logging-server/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/logging-server/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/metrics-server/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/metrics-server/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/metrics-server/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/mutation-server/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/mutation-server/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/mutation-server/src/lib.rs create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/Cargo.toml create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/control_plane.rs create mode 100644 experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/fault-server/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/fault-server/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/fault-server/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/fault-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/fault-server/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/fault-server/src/proto.rs create mode 100644 experimental/mrpc/plugin/policy/logging-server/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/logging-server/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/logging-server/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/logging-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/logging-server/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/logging-server/src/proto.rs create mode 100644 experimental/mrpc/plugin/policy/metrics-server/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/metrics-server/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/metrics-server/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/metrics-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/metrics-server/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/mutation-server/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/mutation-server/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/mutation-server/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/mutation-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/mutation-server/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/mutation-server/src/rpc_hello.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs create mode 100644 experimental/mrpc/plugin/policy/ratelimit-drop-server/src/proto.rs diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 4fc7c88c..34b364fd 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1674,6 +1674,16 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-fault-server" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + [[package]] name = "phoenix-api-policy-fault2" version = "0.1.0" @@ -1725,6 +1735,14 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-logging-server" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-metrics" version = "0.1.0" @@ -1733,6 +1751,14 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-metrics-server" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-mutation" version = "0.1.0" @@ -1741,6 +1767,14 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-mutation-server" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-policy-nofile-logging" version = "0.1.0" @@ -1783,6 +1817,14 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-ratelimit-drop-server" +version = "0.1.0" +dependencies = [ + "phoenix-api", + "serde", +] + [[package]] name = "phoenix-api-rpc-adapter" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 660d82e3..57904404 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -65,7 +65,12 @@ members = [ "phoenix-api/policy/admission-control", "phoenix-api/policy/metrics", "phoenix-api/policy/mutation", - # the pheonix plugins + "phoenix-api/policy/fault-server", + "phoenix-api/policy/logging-server", + "phoenix-api/policy/metrics-server", + "phoenix-api/policy/mutation-server", + "phoenix-api/policy/ratelimit-drop-server", + # the phoenix plugins "plugin/mrpc", "plugin/mrpclb", "plugin/rpc_adapter", @@ -88,6 +93,11 @@ members = [ "plugin/policy/admission-control", "plugin/policy/metrics", "plugin/policy/mutation", + "plugin/policy/fault-server", + "plugin/policy/logging-server", + "plugin/policy/metrics-server", + "plugin/policy/mutation-server", + "plugin/policy/ratelimit-drop-server", # examples "examples/rpc_echo", "examples/rpc_bench", @@ -123,6 +133,12 @@ phoenix-api-policy-delay = { path = "phoenix-api/policy/delay" } phoenix-api-policy-admission-control = { path = "phoenix-api/policy/admission-control" } phoenix-api-policy-metrics = { path = "phoenix-api/policy/metrics" } phoenix-api-policy-mutation = { path = "phoenix-api/policy/mutation" } +phoenix-api-policy-fault-server = { path = "phoenix-api/policy/fault-server" } +phoenix-api-policy-logging-server = { path = "phoenix-api/policy/logging-server" } +phoenix-api-policy-metrics-server = { path = "phoenix-api/policy/metrics-server" } +phoenix-api-policy-mutation-server = { path = "phoenix-api/policy/mutation-server" } +phoenix-api-policy-ratelimit-drop-server = { path = "phoenix-api/policy/ratelimit-drop-server" } + mrpc-build = { path = "mrpc-build" } mrpc-derive = { path = "mrpc-derive" } diff --git a/experimental/mrpc/load-mrpc-plugins.toml b/experimental/mrpc/load-mrpc-plugins.toml index 448beae0..8b9cea2c 100644 --- a/experimental/mrpc/load-mrpc-plugins.toml +++ b/experimental/mrpc/load-mrpc-plugins.toml @@ -138,3 +138,35 @@ config_string = ''' requests_per_sec = 4 bucket_size = 1000 ''' + +[[addons]] +name = "FaultServer" +lib_path = "plugins/libphoenix_fault_server.rlib" +config_string = ''' +''' + +[[addons]] +name = "LoggingServer" +lib_path = "plugins/libphoenix_logging_server.rlib" +config_string = ''' +''' + +[[addons]] +name = "MutationServer" +lib_path = "plugins/libphoenix_mutation_server.rlib" +config_string = ''' +''' + +[[addons]] +name = "MetricsServer" +lib_path = "plugins/libphoenix_metrics_server.rlib" +config_string = ''' +''' + +[[addons]] +name = "RateLimitDropServer" +lib_path = "plugins/libphoenix_ratelimit_drop_server.rlib" +config_string = ''' +requests_per_sec = 4 +bucket_size = 1000 +''' diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/Cargo.toml b/experimental/mrpc/phoenix-api/policy/fault-server/Cargo.toml new file mode 100644 index 00000000..b5b389cb --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/Cargo.toml @@ -0,0 +1,14 @@ + +[package] +name = "phoenix-api-policy-fault-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true +itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/logging/Cargo.toml b/experimental/mrpc/phoenix-api/policy/fault-server/logging/Cargo.toml new file mode 100644 index 00000000..60d4a659 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/logging/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-logging" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/lib.rs b/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/logging/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/fault-server/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/fault-server/src/lib.rs b/experimental/mrpc/phoenix-api/policy/fault-server/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/fault-server/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/logging-server/Cargo.toml b/experimental/mrpc/phoenix-api/policy/logging-server/Cargo.toml new file mode 100644 index 00000000..fcfed524 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/logging-server/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-logging-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/logging-server/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/logging-server/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/logging-server/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/logging-server/src/lib.rs b/experimental/mrpc/phoenix-api/policy/logging-server/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/logging-server/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/metrics-server/Cargo.toml b/experimental/mrpc/phoenix-api/policy/metrics-server/Cargo.toml new file mode 100644 index 00000000..8a0d5c63 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics-server/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-metrics-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/metrics-server/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/metrics-server/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics-server/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/metrics-server/src/lib.rs b/experimental/mrpc/phoenix-api/policy/metrics-server/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/metrics-server/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/mutation-server/Cargo.toml b/experimental/mrpc/phoenix-api/policy/mutation-server/Cargo.toml new file mode 100644 index 00000000..8baea7c9 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation-server/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-mutation-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/mutation-server/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/mutation-server/src/control_plane.rs new file mode 100644 index 00000000..4778cd75 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation-server/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/mutation-server/src/lib.rs b/experimental/mrpc/phoenix-api/policy/mutation-server/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/mutation-server/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/Cargo.toml b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/Cargo.toml new file mode 100644 index 00000000..211984a9 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "phoenix-api-policy-ratelimit-drop-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix-api.workspace = true + +serde.workspace = true diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/control_plane.rs b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/control_plane.rs new file mode 100644 index 00000000..dc317e5f --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/control_plane.rs @@ -0,0 +1,14 @@ +use serde::{Deserialize, Serialize}; + +type IResult = Result; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + NewConfig(u64, u64), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ResponseKind {} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response(pub IResult); diff --git a/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/lib.rs b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/lib.rs new file mode 100644 index 00000000..412c5a55 --- /dev/null +++ b/experimental/mrpc/phoenix-api/policy/ratelimit-drop-server/src/lib.rs @@ -0,0 +1 @@ +pub mod control_plane; diff --git a/experimental/mrpc/plugin/policy/fault-server/Cargo.toml b/experimental/mrpc/plugin/policy/fault-server/Cargo.toml new file mode 100644 index 00000000..1bf2d0ec --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/Cargo.toml @@ -0,0 +1,28 @@ + +[package] +name = "phoenix-FaultServer-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix_common.workspace = true +phoenix-api-policy-FaultServer.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +chrono.workspace = true +itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/plugin/policy/fault-server/src/config.rs b/experimental/mrpc/plugin/policy/fault-server/src/config.rs new file mode 100644 index 00000000..199a271b --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/src/config.rs @@ -0,0 +1,37 @@ +use chrono::{Datelike, Timelike, Utc}; +use phoenix_common::log; +use serde::{Deserialize, Serialize}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +#[derive(Debug, Clone, Copy, DeFaultServer, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct FaultServerConfig {} + +impl FaultServerConfig { + /// Get config from toml file + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} + +pub fn create_log_file() -> std::fs::File { + std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); + let now = Utc::now(); + let date_string = format!( + "{}-{}-{}-{}-{}-{}", + now.year(), + now.month(), + now.day(), + now.hour(), + now.minute(), + now.second() + ); + let file_name = format!("/tmp/phoenix/log/logging_engine_{}.log", date_string); + ///log::info!("create log file {}", file_name); + let log_file = std::fs::File::create(file_name).expect("create file failed"); + log_file +} diff --git a/experimental/mrpc/plugin/policy/fault-server/src/engine.rs b/experimental/mrpc/plugin/policy/fault-server/src/engine.rs new file mode 100644 index 00000000..8a939fb2 --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/src/engine.rs @@ -0,0 +1,238 @@ +use anyhow::{anyhow, Result}; +use futures::future::BoxFuture; +use phoenix_api::rpc::{RpcId, TransportStatus}; +use std::fmt; +use std::fs::File; +use std::io::Write; +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; + +use phoenix_api_policy_FaultServer::control_plane; + +use phoenix_common::engine::datapath::message::{ + EngineRxMessage, EngineTxMessage, RpcMessageGeneral, +}; + +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; + +use phoenix_common::engine::datapath::RpcMessageTx; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::{create_log_file, FaultServerConfig}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub mod hello { + include!("proto.rs"); +} + +fn hello_request_name_readonly(req: &hello::HelloRequest) -> String { + let buf = &req.name as &[u8]; + String::from_utf8_lossy(buf).to_string().clone() +} + +pub(crate) struct FaultServerEngine { + pub(crate) node: DataPathNode, + pub(crate) indicator: Indicator, + pub(crate) config: FaultServerConfig, + pub(crate) var_probability: f32, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for FaultServerEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "FaultServerEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + self.config = FaultServerConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(FaultServerEngine, node); + +impl Decompose for FaultServerEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + let mut collections = ResourceCollection::with_capacity(4); + collections.insert("config".to_string(), Box::new(engine.config)); + (collections, engine.node) + } +} + +impl FaultServerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let var_probability = 0.01; + + let engine = FaultServerEngine { + node, + indicator: DeFaultServer::deFaultServer(), + config, + var_probability, + }; + Ok(engine) + } +} + +impl FaultServerEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + self.indicator.set_nwork(work); + future::yield_now().await; + } + } +} + +#[inline] +fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_ref().unwrap() }; + return req; +} + +impl FaultServerEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + let mut input = Vec::new(); + input.push(msg); + let output: Vec<_> = input + .iter() + .map(|msg| { + let rpc_message = materialize_nocopy(&msg); + let conn_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.call_id; + let rpc_id = RpcId::new(conn_id, call_id); + if rand::random::() < self.var_probability { + let error = EngineRxMessage::Ack( + rpc_id, + TransportStatus::Error(unsafe { + NonZeroU32::new_unchecked(403) + }), + ); + RpcMessageGeneral::RxMessage(error) + } else { + let raw_ptr: *const hello::HelloRequest = rpc_message; + let new_msg = RpcMessageTx { + meta_buf_ptr: msg.meta_buf_ptr.clone(), + addr_backend: raw_ptr.addr(), + }; + RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage( + new_msg, + )) + } + }) + .collect(); + + for msg in output { + match msg { + RpcMessageGeneral::TxMessage(msg) => { + self.tx_outputs()[0].send(msg)?; + } + RpcMessageGeneral::RxMessage(msg) => { + self.rx_outputs()[0].send(msg)?; + } + _ => {} + } + } + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineRxMessage::Ack(rpc_id, status) => { + // todo + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + EngineRxMessage::RpcMessage(msg) => { + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => self.rx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/fault-server/src/lib.rs b/experimental/mrpc/plugin/policy/fault-server/src/lib.rs new file mode 100644 index 00000000..b833dc14 --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/src/lib.rs @@ -0,0 +1,37 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] +use thiserror::Error; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::FaultServerConfig; +use crate::module::FaultServerAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = FaultServerConfig::new(config_string)?; + let addon = FaultServerAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/fault-server/src/module.rs b/experimental/mrpc/plugin/policy/fault-server/src/module.rs new file mode 100644 index 00000000..f986450f --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/src/module.rs @@ -0,0 +1,106 @@ +use anyhow::{bail, Result}; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::FaultServerEngine; +use crate::config::{create_log_file, FaultServerConfig}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + +pub(crate) struct FaultServerEngineBuilder { + node: DataPathNode, + config: FaultServerConfig, +} + +impl FaultServerEngineBuilder { + fn new(node: DataPathNode, config: FaultServerConfig) -> Self { + FaultServerEngineBuilder { node, config } + } + // TODO! LogFile + fn build(self) -> Result { + let var_probability = 0.01; + + Ok(FaultServerEngine { + node: self.node, + indicator: DeFaultServer::deFaultServer(), + config: self.config, + var_probability, + }) + } +} + +pub struct FaultServerAddon { + config: FaultServerConfig, +} + +impl FaultServerAddon { + pub const FaultServer_ENGINE: EngineType = EngineType("FaultServerEngine"); + pub const ENGINES: &'static [EngineType] = &[FaultServerAddon::FaultServer_ENGINE]; +} + +impl FaultServerAddon { + pub fn new(config: FaultServerConfig) -> Self { + FaultServerAddon { config } + } +} + +impl PhoenixAddon for FaultServerAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + FaultServerAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != FaultServerAddon::FaultServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = FaultServerEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != FaultServerAddon::FaultServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = FaultServerEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/fault-server/src/proto.rs b/experimental/mrpc/plugin/policy/fault-server/src/proto.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/fault-server/src/proto.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } diff --git a/experimental/mrpc/plugin/policy/logging-server/Cargo.toml b/experimental/mrpc/plugin/policy/logging-server/Cargo.toml new file mode 100644 index 00000000..e058ccd2 --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "phoenix-LoggingServer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix_common.workspace = true +phoenix-api-policy-LoggingServer.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +chrono.workspace = true +itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/plugin/policy/logging-server/src/config.rs b/experimental/mrpc/plugin/policy/logging-server/src/config.rs new file mode 100644 index 00000000..5ba0472b --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/src/config.rs @@ -0,0 +1,41 @@ +//! template file for engine config +//! we can add custome functions here +//! so that the whole crate can import the function + +use chrono::{Datelike, Timelike, Utc}; +use phoenix_common::log; +use serde::{Deserialize, Serialize}; + +/// currently, LoggingServer engine does not need a config +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct LoggingServerConfig {} + +impl LoggingServerConfig { + /// Get config from toml file + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} + +/// Create a log file in `/tmp/phoenix/log` +/// This function will be called every time +/// a LoggingServer engine is started or restored +pub fn create_log_file() -> std::fs::File { + std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); + let now = Utc::now(); + let date_string = format!( + "{}-{}-{}-{}-{}-{}", + now.year(), + now.month(), + now.day(), + now.hour(), + now.minute(), + now.second() + ); + let file_name = format!("/tmp/phoenix/log/LoggingServer_engine_{}.log", date_string); + log::info!("create log file {}", file_name); + let log_file = std::fs::File::create(file_name).expect("create file failed"); + log_file +} diff --git a/experimental/mrpc/plugin/policy/logging-server/src/engine.rs b/experimental/mrpc/plugin/policy/logging-server/src/engine.rs new file mode 100644 index 00000000..0b219a85 --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/src/engine.rs @@ -0,0 +1,239 @@ +//! main logic happens here +use anyhow::{anyhow, Result}; +use chrono::Utc; +use futures::future::BoxFuture; +use phoenix_api_policy_LoggingServer::control_plane; +use phoenix_common::engine::datapath::RpcMessageTx; +use std::io::Write; +use std::os::unix::ucred::UCred; +use std::pin::Pin; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage}; + +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::{create_log_file, LoggingServerConfig}; + +pub mod hello { + include!("proto.rs"); +} + +/// The internal state of an LoggingServer engine, +/// it contains some template fields like `node`, `indicator`, +/// a config field, in that case `LoggingServerConfig` +/// and other custome fields like `log_file +pub(crate) struct LoggingServerEngine { + pub(crate) node: DataPathNode, + pub(crate) indicator: Indicator, + pub(crate) config: LoggingServerConfig, + /// log_file is where the log will be written into + /// it is temperoray, i.e. we don't store it when restart + pub(crate) log_file: std::fs::File, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +/// template +impl Engine for LoggingServerEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "LoggingServerEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + self.config = LoggingServerConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(LoggingServerEngine, node); + +impl Decompose for LoggingServerEngine { + /// flush will be called when we need to clean the transient state before decompose + /// # return + /// * `Result` - number of work drained from tx & rx queue + fn flush(&mut self) -> Result { + let mut work = 0; + /// drain the rx & tx queue + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + self.log_file.flush()?; + // file will automatically be closed when the engine is dropped + Ok(work) + } + + /// template + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + let mut collections = ResourceCollection::with_capacity(4); + collections.insert("config".to_string(), Box::new(engine.config)); + (collections, engine.node) + } +} + +impl LoggingServerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let log_file = create_log_file(); + let engine = LoggingServerEngine { + node, + indicator: Default::default(), + config, + log_file, + }; + Ok(engine) + } +} + +impl LoggingServerEngine { + async fn mainloop(&mut self) -> EngineResult { + // open a write buffer to a file + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +#[inline] +fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_ref().unwrap() }; + return req; +} + +impl LoggingServerEngine { + /// main logic about handling rx & tx input messages + /// note that a LoggingServer engine can be deployed in client-side or server-side + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + // tx logic + // For server it is `On-Response` logic, when sending response to network + // For client it is `On-Request` logic, when sending request to network + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + // we care only log RPCs + // other types like ACK should not be logged since they are not + // ACKs between Client/Server, but communication between engines + // "Real" ACKs are logged in rx logic + EngineTxMessage::RpcMessage(msg) => { + // we get the metadata of RPC from the shared memory + let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + let rpc_message = materialize_nocopy(&msg); + // write the metadata into the file + // since meta_ref implements Debug, we can use {:?} + // rather than manully parse the metadata struct + write!( + self.log_file, + "{}{}{}{}{}\n", + Utc::now(), + format!("{:?}", meta_ref.msg_type), + format!("{:?}", meta_ref.conn_id), + format!("{:?}", meta_ref.conn_id), + format!("{}", String::from_utf8_lossy(&rpc_message.name)), + ) + .unwrap(); + + // after LoggingServer, we forward the message to the next engine + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + // if received message is not RPC, we simple forward it + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + + // tx logic + // For server it is `On-Request` logic, when recving request from network + // For client it is `On-Response` logic, when recving response from network + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + // ACK means that + // If I am client: server received my request + // If I am server: client recevied my response + EngineRxMessage::Ack(rpc_id, status) => { + // log the info to the file + // forward the message + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + EngineRxMessage::RpcMessage(msg) => { + // forward the message + // again, this RpcMessage is not the application-level rpc + // so we don log them + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + // forward other unknown msg + m => self.rx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/logging-server/src/lib.rs b/experimental/mrpc/plugin/policy/logging-server/src/lib.rs new file mode 100644 index 00000000..d036b86a --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/src/lib.rs @@ -0,0 +1,33 @@ +//! template file for export + +#![feature(peer_credentials_unix_socket)] +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::LoggingServerConfig; +use crate::module::LoggingServerAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = LoggingServerConfig::new(config_string)?; + let addon = LoggingServerAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/logging-server/src/module.rs b/experimental/mrpc/plugin/policy/logging-server/src/module.rs new file mode 100644 index 00000000..11fd6475 --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/src/module.rs @@ -0,0 +1,105 @@ +//! template file for an engine +//! we only need to change the args in config and engine constructor + +use anyhow::{bail, Result}; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::LoggingServerEngine; +use crate::config::{create_log_file, LoggingServerConfig}; + +pub(crate) struct LoggingServerEngineBuilder { + node: DataPathNode, + config: LoggingServerConfig, +} + +impl LoggingServerEngineBuilder { + fn new(node: DataPathNode, config: LoggingServerConfig) -> Self { + LoggingServerEngineBuilder { node, config } + } + + fn build(self) -> Result { + let log_file = create_log_file(); + + Ok(LoggingServerEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + log_file, + }) + } +} + +pub struct LoggingServerAddon { + config: LoggingServerConfig, +} + +impl LoggingServerAddon { + pub const LoggingServer_ENGINE: EngineType = EngineType("LoggingServerEngine"); + pub const ENGINES: &'static [EngineType] = &[LoggingServerAddon::LoggingServer_ENGINE]; +} + +impl LoggingServerAddon { + pub fn new(config: LoggingServerConfig) -> Self { + LoggingServerAddon { config } + } +} + +impl PhoenixAddon for LoggingServerAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + LoggingServerAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != LoggingServerAddon::LoggingServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = LoggingServerEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != LoggingServerAddon::LoggingServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = LoggingServerEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/logging-server/src/proto.rs b/experimental/mrpc/plugin/policy/logging-server/src/proto.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/logging-server/src/proto.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } diff --git a/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml b/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml new file mode 100644 index 00000000..b5118932 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "phoenix-metrics" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +phoenix-api-policy-metrics.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true + +phoenix_common.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +fnv.workspace = true diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/config.rs b/experimental/mrpc/plugin/policy/metrics-server/src/config.rs new file mode 100644 index 00000000..eca26592 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics-server/src/config.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MetricsServerConfig {} + +impl MetricsServerConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs b/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs new file mode 100644 index 00000000..138fef39 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs @@ -0,0 +1,191 @@ +//! This engine can only be placed at the sender side for now. +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; + +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap as HashMap; +use futures::future::BoxFuture; + +use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; +use phoenix_api_policy_MetricsServer::control_plane; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::MetricsServerConfig; + +pub(crate) struct MetricsServerEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + pub(crate) num_succ: u32, + pub(crate) num_rej: u32, + + pub(crate) config: MetricsServerConfig, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for MetricsServerEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "MetricsServerEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + // Update config + self.config = MetricsServerConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(MetricsServerEngine, node); + +impl Decompose for MetricsServerEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(2); + collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("num_rej".to_string(), Box::new(engine.num_rej)); + collections.insert("num_succ".to_string(), Box::new(engine.num_succ)); + (collections, engine.node) + } +} + +impl MetricsServerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_succ = *local + .remove("num_succ") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_rej = *local + .remove("num_rej") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let engine = MetricsServerEngine { + node, + indicator: Default::default(), + num_succ, + num_rej, + config, + }; + Ok(engine) + } +} + +impl MetricsServerEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +impl MetricsServerEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + self.tx_outputs()[0].send(msg)?; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + // forward all rx msgs + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + match m { + EngineRxMessage::RpcMessage(msg) => { + let meta = unsafe { &*msg.meta.as_ptr() }; + if meta.status_code == StatusCode::Success { + self.num_succ += 1; + } else { + self.num_rej += 1; + } + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => { + self.rx_outputs()[0].send(m)?; + } + }; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/lib.rs b/experimental/mrpc/plugin/policy/metrics-server/src/lib.rs new file mode 100644 index 00000000..c6a5d526 --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics-server/src/lib.rs @@ -0,0 +1,34 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::MetricsServerConfig; +use crate::module::MetricsServerAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = MetricsServerConfig::new(config_string)?; + let addon = MetricsServerAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/module.rs b/experimental/mrpc/plugin/policy/metrics-server/src/module.rs new file mode 100644 index 00000000..d1225bce --- /dev/null +++ b/experimental/mrpc/plugin/policy/metrics-server/src/module.rs @@ -0,0 +1,102 @@ +use anyhow::{bail, Result}; +use fnv::FnvHashMap as HashMap; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::MetricsServerEngine; +use crate::config::MetricsServerConfig; + +pub(crate) struct MetricsServerEngineBuilder { + node: DataPathNode, + config: MetricsServerConfig, +} + +impl MetricsServerEngineBuilder { + fn new(node: DataPathNode, config: MetricsServerConfig) -> Self { + MetricsServerEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(MetricsServerEngine { + node: self.node, + indicator: Default::default(), + num_succ: 0, + num_rej: 0, + config: self.config, + }) + } +} + +pub struct MetricsServerAddon { + config: MetricsServerConfig, +} + +impl MetricsServerAddon { + pub const MetricsServer_ENGINE: EngineType = EngineType("MetricsServerEngine"); + pub const ENGINES: &'static [EngineType] = &[MetricsServerAddon::MetricsServer_ENGINE]; +} + +impl MetricsServerAddon { + pub fn new(config: MetricsServerConfig) -> Self { + MetricsServerAddon { config } + } +} + +impl PhoenixAddon for MetricsServerAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + MetricsServerAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != MetricsServerAddon::MetricsServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = MetricsServerEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != MetricsServerAddon::MetricsServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = MetricsServerEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml b/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml new file mode 100644 index 00000000..da4953c0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "phoenix-mutation" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +phoenix-api-policy-mutation.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true + +phoenix_common.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +fnv.workspace = true diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/config.rs b/experimental/mrpc/plugin/policy/mutation-server/src/config.rs new file mode 100644 index 00000000..8928ba65 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/src/config.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MutationServerConfig {} + +impl MutationServerConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs b/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs new file mode 100644 index 00000000..eadc2dbc --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs @@ -0,0 +1,195 @@ +//! This engine can only be placed at the sender side for now. +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; + +use anyhow::{anyhow, Result}; +use fnv::FnvHashMap as HashMap; +use futures::future::BoxFuture; + +use phoenix_api::rpc::{RpcId, TransportStatus}; +use phoenix_api_policy_MutationServer::control_plane; + +use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; + +use super::DatapathError; +use crate::config::MutationServerConfig; + +pub(crate) struct MutationServerEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + pub(crate) config: MutationServerConfig, + + pub(crate) target: String, +} + +pub mod hello { + // The string specified here must match the proto package name + include!("rpc_hello.rs"); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for MutationServerEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "MutationServerEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig() => { + // Update config + self.config = MutationServerConfig {}; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(MutationServerEngine, node); + +impl Decompose for MutationServerEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(2); + collections.insert("target".to_string(), Box::new(engine.target)); + collections.insert("config".to_string(), Box::new(engine.config)); + (collections, engine.node) + } +} + +impl MutationServerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let target = *local + .remove("target") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let engine = MutationServerEngine { + node, + indicator: Default::default(), + target, + config, + }; + Ok(engine) + } +} + +impl MutationServerEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +/// Copy the RPC request to a private heap and returns the request. +#[inline] +fn materialize(msg: &RpcMessageTx) -> Box { + let req_ptr = Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_ref() }; + // returns a private_req + Box::new(req.clone()) +} + +impl MutationServerEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let mut req_ptr = + Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_mut() }; + for i in 0..req.name.len() { + req.name[i] = 'a' as u8; + } + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + // forward all rx msgs + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + self.rx_outputs()[0].send(m)?; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/lib.rs b/experimental/mrpc/plugin/policy/mutation-server/src/lib.rs new file mode 100644 index 00000000..6705cf79 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/src/lib.rs @@ -0,0 +1,34 @@ +#![feature(peer_credentials_unix_socket)] +#![feature(ptr_internals)] +#![feature(strict_provenance)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::MutationServerConfig; +use crate::module::MutationServerAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = MutationServerConfig::new(config_string)?; + let addon = MutationServerAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/module.rs b/experimental/mrpc/plugin/policy/mutation-server/src/module.rs new file mode 100644 index 00000000..d8683ad1 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/src/module.rs @@ -0,0 +1,101 @@ +use anyhow::{bail, Result}; +use fnv::FnvHashMap as HashMap; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::MutationServerEngine; +use crate::config::MutationServerConfig; + +pub(crate) struct MutationServerEngineBuilder { + node: DataPathNode, + config: MutationServerConfig, +} + +impl MutationServerEngineBuilder { + fn new(node: DataPathNode, config: MutationServerConfig) -> Self { + MutationServerEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(MutationServerEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + target: "Banana".to_string(), + }) + } +} + +pub struct MutationServerAddon { + config: MutationServerConfig, +} + +impl MutationServerAddon { + pub const MutationServer_ENGINE: EngineType = EngineType("MutationServerEngine"); + pub const ENGINES: &'static [EngineType] = &[MutationServerAddon::MutationServer_ENGINE]; +} + +impl MutationServerAddon { + pub fn new(config: MutationServerConfig) -> Self { + MutationServerAddon { config } + } +} + +impl PhoenixAddon for MutationServerAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + MutationServerAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != MutationServerAddon::MutationServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = MutationServerEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != MutationServerAddon::MutationServer_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = MutationServerEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/rpc_hello.rs b/experimental/mrpc/plugin/policy/mutation-server/src/rpc_hello.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/mutation-server/src/rpc_hello.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml b/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml new file mode 100644 index 00000000..4b592492 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "phoenix-ratelimit-drop" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phoenix_common.workspace = true +phoenix-api-policy-ratelimit-drop.workspace = true + +futures.workspace = true +minstant.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +anyhow.workspace = true +nix.workspace = true +toml = { workspace = true, features = ["preserve_order"] } +bincode.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } +chrono.workspace = true +itertools.workspace = true diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs new file mode 100644 index 00000000..2d4bdeb0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct RateLimitDropServerConfig { + pub requests_per_sec: u64, + pub bucket_size: u64, +} + +impl Default for RateLimitDropServerConfig { + fn default() -> Self { + RateLimitDropServerConfig { + requests_per_sec: 100000, + bucket_size: 100000, + } + } +} + +impl RateLimitDropServerConfig { + pub fn new(config: Option<&str>) -> anyhow::Result { + let config = toml::from_str(config.unwrap_or(""))?; + Ok(config) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs new file mode 100644 index 00000000..b95b210d --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs @@ -0,0 +1,260 @@ +use std::collections::VecDeque; +use std::os::unix::ucred::UCred; +use std::pin::Pin; + +use super::DatapathError; +use crate::config::RateLimitDropServerConfig; +use anyhow::{anyhow, Result}; +use futures::future::BoxFuture; +use minstant::Instant; +use phoenix_api::rpc::{RpcId, TransportStatus}; +use phoenix_api_policy_ratelimit_drop::control_plane; +use phoenix_common::engine::datapath::message::{EngineTxMessage, RpcMessageGeneral, RpcMessageTx}; +use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::datapath::EngineRxMessage; +use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; +use phoenix_common::envelop::ResourceDowncast; +use phoenix_common::impl_vertex_for_engine; +use phoenix_common::log; +use phoenix_common::module::Version; +use phoenix_common::storage::{ResourceCollection, SharedStorage}; +use std::num::NonZeroU32; + +pub mod hello { + include!("proto.rs"); +} + +fn hello_request_name_readonly(req: &hello::HelloRequest) -> String { + let buf = &req.name as &[u8]; + String::from_utf8_lossy(buf).to_string().clone() +} + +pub(crate) struct RateLimitDropServerEngine { + pub(crate) node: DataPathNode, + + pub(crate) indicator: Indicator, + + // A set of func_ids to apply the rate limit. + // TODO(cjr): maybe put this filter in a separate engine like FilterEngine/ClassiferEngine. + // pub(crate) filter: FnvHashSet, + // Number of tokens to add for each seconds. + pub(crate) config: RateLimitDropServerConfig, + // The most recent timestamp we add the token to the bucket. + pub(crate) last_ts: Instant, + // The number of available tokens in the token bucket algorithm. + pub(crate) num_tokens: f64, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Progress(usize), + Disconnected, +} + +use Status::Progress; + +impl Engine for RateLimitDropServerEngine { + fn activate<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, EngineResult> { + Box::pin(async move { self.get_mut().mainloop().await }) + } + + fn description(self: Pin<&Self>) -> String { + "RateLimitDropServerEngine".to_owned() + } + + #[inline] + fn tracker(self: Pin<&mut Self>) -> &mut Indicator { + &mut self.get_mut().indicator + } + + fn handle_request(&mut self, request: Vec, _cred: UCred) -> Result<()> { + let request: control_plane::Request = bincode::deserialize(&request[..])?; + + match request { + control_plane::Request::NewConfig(requests_per_sec, bucket_size) => { + self.config = RateLimitDropServerConfig { + requests_per_sec, + bucket_size, + }; + } + } + Ok(()) + } +} + +impl_vertex_for_engine!(RateLimitDropServerEngine, node); + +impl Decompose for RateLimitDropServerEngine { + fn flush(&mut self) -> Result { + let mut work = 0; + while !self.tx_inputs()[0].is_empty() { + if let Progress(n) = self.check_input_queue()? { + work += n; + } + } + + Ok(work) + } + + fn decompose( + self: Box, + _shared: &mut SharedStorage, + _global: &mut ResourceCollection, + ) -> (ResourceCollection, DataPathNode) { + let engine = *self; + + let mut collections = ResourceCollection::with_capacity(4); + collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("last_ts".to_string(), Box::new(engine.last_ts)); + collections.insert("num_tokens".to_string(), Box::new(engine.num_tokens)); + (collections, engine.node) + } +} + +impl RateLimitDropServerEngine { + pub(crate) fn restore( + mut local: ResourceCollection, + node: DataPathNode, + _prev_version: Version, + ) -> Result { + let config = *local + .remove("config") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let last_ts: Instant = *local + .remove("last_ts") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let num_tokens = *local + .remove("num_tokens") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + + let engine = RateLimitDropServerEngine { + node, + indicator: Default::default(), + config, + last_ts, + num_tokens, + }; + Ok(engine) + } +} + +impl RateLimitDropServerEngine { + async fn mainloop(&mut self) -> EngineResult { + loop { + let mut work = 0; + // check input queue, ~100ns + loop { + match self.check_input_queue()? { + Progress(0) => break, + Progress(n) => work += n, + Status::Disconnected => return Ok(()), + } + } + + // If there's pending receives, there will always be future work to do. + self.indicator.set_nwork(work); + + future::yield_now().await; + } + } +} + +fn current_timestamp() -> Instant { + Instant::now() +} + +#[inline] +fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_ref().unwrap() }; + return req; +} + +impl RateLimitDropServerEngine { + fn check_input_queue(&mut self) -> Result { + use phoenix_common::engine::datapath::TryRecvError; + + match self.tx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineTxMessage::RpcMessage(msg) => { + let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + let mut input = Vec::new(); + input.push(msg); + self.num_tokens = self.num_tokens + + (current_timestamp() - self.last_ts).as_secs_f64() + * self.config.requests_per_sec as f64; + self.last_ts = current_timestamp(); + log::debug!("num_tokens: {}", self.num_tokens); + let limit = std::cmp::min(input.len() as i64, self.num_tokens as i64); + self.num_tokens = self.num_tokens - limit as f64; + + let output = input.iter().enumerate().map(|(index, req)| { + let rpc_message = materialize_nocopy(&req); + let conn_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.call_id; + let rpc_id = RpcId::new(conn_id, call_id); + if index < limit as usize { + let raw_ptr: *const hello::HelloRequest = rpc_message; + let new_msg = RpcMessageTx { + meta_buf_ptr: req.meta_buf_ptr.clone(), + addr_backend: req.addr_backend, + }; + RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage(new_msg)) + } else { + let error = EngineRxMessage::Ack( + rpc_id, + TransportStatus::Error(unsafe { + NonZeroU32::new_unchecked(403) + }), + ); + RpcMessageGeneral::RxMessage(error) + } + }); + for msg in output { + match msg { + RpcMessageGeneral::TxMessage(msg) => { + self.tx_outputs()[0].send(msg)?; + } + RpcMessageGeneral::RxMessage(msg) => { + self.rx_outputs()[0].send(msg)?; + } + _ => {} + } + } + } + m => self.tx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + match self.rx_inputs()[0].try_recv() { + Ok(msg) => { + match msg { + EngineRxMessage::Ack(rpc_id, status) => { + // todo + self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + } + EngineRxMessage::RpcMessage(msg) => { + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + m => self.rx_outputs()[0].send(m)?, + } + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => { + return Ok(Status::Disconnected); + } + } + Ok(Progress(0)) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs new file mode 100644 index 00000000..b77ef8bd --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs @@ -0,0 +1,32 @@ +#![feature(peer_credentials_unix_socket)] + +use thiserror::Error; + +pub use phoenix_common::{InitFnResult, PhoenixAddon}; + +pub mod config; +pub(crate) mod engine; +pub mod module; + +#[derive(Error, Debug)] +pub(crate) enum DatapathError { + #[error("Internal queue send error")] + InternalQueueSend, +} + +use phoenix_common::engine::datapath::SendError; +impl From> for DatapathError { + fn from(_other: SendError) -> Self { + DatapathError::InternalQueueSend + } +} + +use crate::config::RateLimitDropServerConfig; +use crate::module::RateLimitDropServerAddon; + +#[no_mangle] +pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { + let config = RateLimitDropServerConfig::new(config_string)?; + let addon = RateLimitDropServerAddon::new(config); + Ok(Box::new(addon)) +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs new file mode 100644 index 00000000..baa16ebb --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs @@ -0,0 +1,104 @@ +use std::collections::VecDeque; + +use anyhow::{bail, Result}; +use minstant::Instant; +use nix::unistd::Pid; + +use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::DataPathNode; +use phoenix_common::engine::{Engine, EngineType}; +use phoenix_common::storage::ResourceCollection; + +use super::engine::RateLimitDropServerEngine; +use crate::config::RateLimitDropServerConfig; + +pub(crate) struct RateLimitDropServerEngineBuilder { + node: DataPathNode, + config: RateLimitDropServerConfig, +} + +impl RateLimitDropServerEngineBuilder { + fn new(node: DataPathNode, config: RateLimitDropServerConfig) -> Self { + RateLimitDropServerEngineBuilder { node, config } + } + + fn build(self) -> Result { + Ok(RateLimitDropServerEngine { + node: self.node, + indicator: Default::default(), + config: self.config, + last_ts: Instant::now(), + num_tokens: self.config.bucket_size as _, + }) + } +} + +pub struct RateLimitDropServerAddon { + config: RateLimitDropServerConfig, +} + +impl RateLimitDropServerAddon { + pub const RATE_LIMIT_DROP_ENGINE: EngineType = EngineType("RateLimitDropServerEngine"); + pub const ENGINES: &'static [EngineType] = &[RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE]; +} + +impl RateLimitDropServerAddon { + pub fn new(config: RateLimitDropServerConfig) -> Self { + RateLimitDropServerAddon { config } + } +} + +impl PhoenixAddon for RateLimitDropServerAddon { + fn check_compatibility(&self, _prev: Option<&Version>) -> bool { + true + } + + fn decompose(self: Box) -> ResourceCollection { + let addon = *self; + let mut collections = ResourceCollection::new(); + collections.insert("config".to_string(), Box::new(addon.config)); + collections + } + + #[inline] + fn migrate(&mut self, _prev_addon: Box) {} + + fn engines(&self) -> &[EngineType] { + RateLimitDropServerAddon::ENGINES + } + + fn update_config(&mut self, config: &str) -> Result<()> { + self.config = toml::from_str(config)?; + Ok(()) + } + + fn create_engine( + &mut self, + ty: EngineType, + _pid: Pid, + node: DataPathNode, + ) -> Result> { + if ty != RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let builder = RateLimitDropServerEngineBuilder::new(node, self.config); + let engine = builder.build()?; + Ok(Box::new(engine)) + } + + fn restore_engine( + &mut self, + ty: EngineType, + local: ResourceCollection, + node: DataPathNode, + prev_version: Version, + ) -> Result> { + if ty != RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE { + bail!("invalid engine type {:?}", ty) + } + + let engine = RateLimitDropServerEngine::restore(local, node, prev_version)?; + Ok(Box::new(engine)) + } +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/proto.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/proto.rs new file mode 100644 index 00000000..83ee8ab0 --- /dev/null +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/proto.rs @@ -0,0 +1,29 @@ +/// The request message containing the user's name. +#[repr(C)] +#[derive(Debug, Clone, ::mrpc_derive::Message)] +pub struct HelloRequest { + #[prost(bytes = "vec", tag = "1")] + pub name: ::mrpc_marshal::shadow::Vec, +} +/// The response message containing the greetings +#[repr(C)] +#[derive(Debug, ::mrpc_derive::Message)] +pub struct HelloReply { + #[prost(bytes = "vec", tag = "1")] + pub message: ::mrpc_marshal::shadow::Vec, +} + +// /// The request message containing the user's name. +// #[repr(C)] +// #[derive(Debug, Clone, ::mrpc_derive::Message)] +// pub struct HelloRequest { +// #[prost(bytes = "vec", tag = "1")] +// pub name: ::mrpc::alloc::Vec, +// } +// /// The response message containing the greetings +// #[repr(C)] +// #[derive(Debug, ::mrpc_derive::Message)] +// pub struct HelloReply { +// #[prost(bytes = "vec", tag = "1")] +// pub message: ::mrpc::alloc::Vec, +// } From b5b8c2f5b1f5d48becef54c58ee07f106f348ea1 Mon Sep 17 00:00:00 2001 From: banruo Date: Sat, 2 Dec 2023 18:02:49 +0000 Subject: [PATCH 15/21] add server side impls --- experimental/mrpc/Cargo.lock | 116 +++++++++++++ .../plugin/policy/fault-server/Cargo.toml | 4 +- .../plugin/policy/fault-server/src/config.rs | 2 +- .../plugin/policy/fault-server/src/engine.rs | 132 +++++++------- .../plugin/policy/fault-server/src/module.rs | 19 +- .../plugin/policy/logging-server/Cargo.toml | 4 +- .../policy/logging-server/src/config.rs | 6 +- .../policy/logging-server/src/engine.rs | 78 +++------ .../plugin/policy/logging-server/src/lib.rs | 2 +- .../policy/logging-server/src/module.rs | 8 +- .../plugin/policy/metrics-server/Cargo.toml | 4 +- .../policy/metrics-server/src/engine.rs | 32 ++-- .../policy/metrics-server/src/module.rs | 8 +- .../plugin/policy/mutation-server/Cargo.toml | 4 +- .../policy/mutation-server/src/engine.rs | 43 ++--- .../policy/mutation-server/src/module.rs | 8 +- .../policy/ratelimit-drop-server/Cargo.toml | 14 +- .../ratelimit-drop-server/src/config.rs | 24 +++ .../ratelimit-drop-server/src/engine.rs | 164 ++++++++++-------- .../policy/ratelimit-drop-server/src/lib.rs | 7 +- .../ratelimit-drop-server/src/module.rs | 23 ++- 21 files changed, 425 insertions(+), 277 deletions(-) diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 34b364fd..f862caf6 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1927,6 +1927,30 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-fault-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-fault-server", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-fault2" version = "0.1.0" @@ -2096,6 +2120,30 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-logging-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-logging-server", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-metrics" version = "0.1.0" @@ -2118,6 +2166,28 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-metrics-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-metrics-server", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-mrpc" version = "0.1.0" @@ -2204,6 +2274,28 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-mutation-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "fnv", + "futures", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-mutation-server", + "phoenix_common", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-nofile-logging" version = "0.1.0" @@ -2301,6 +2393,30 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-ratelimit-drop-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-ratelimit-drop-server", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-rpc-adapter" version = "0.1.0" diff --git a/experimental/mrpc/plugin/policy/fault-server/Cargo.toml b/experimental/mrpc/plugin/policy/fault-server/Cargo.toml index 1bf2d0ec..ad5454f2 100644 --- a/experimental/mrpc/plugin/policy/fault-server/Cargo.toml +++ b/experimental/mrpc/plugin/policy/fault-server/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "phoenix-FaultServer-server" +name = "phoenix-fault-server" version = "0.1.0" edition = "2021" @@ -8,7 +8,7 @@ edition = "2021" [dependencies] phoenix_common.workspace = true -phoenix-api-policy-FaultServer.workspace = true +phoenix-api-policy-fault-server.workspace = true mrpc-marshal.workspace = true mrpc-derive.workspace = true shm.workspace = true diff --git a/experimental/mrpc/plugin/policy/fault-server/src/config.rs b/experimental/mrpc/plugin/policy/fault-server/src/config.rs index 199a271b..fa8605e5 100644 --- a/experimental/mrpc/plugin/policy/fault-server/src/config.rs +++ b/experimental/mrpc/plugin/policy/fault-server/src/config.rs @@ -6,7 +6,7 @@ use chrono::prelude::*; use itertools::iproduct; use rand::Rng; -#[derive(Debug, Clone, Copy, DeFaultServer, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct FaultServerConfig {} diff --git a/experimental/mrpc/plugin/policy/fault-server/src/engine.rs b/experimental/mrpc/plugin/policy/fault-server/src/engine.rs index 8a939fb2..b55b016d 100644 --- a/experimental/mrpc/plugin/policy/fault-server/src/engine.rs +++ b/experimental/mrpc/plugin/policy/fault-server/src/engine.rs @@ -1,18 +1,19 @@ use anyhow::{anyhow, Result}; use futures::future::BoxFuture; -use phoenix_api::rpc::{RpcId, TransportStatus}; +use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; use std::fmt; use std::fs::File; use std::io::Write; use std::num::NonZeroU32; use std::os::unix::ucred::UCred; use std::pin::Pin; +use std::ptr::Unique; -use phoenix_api_policy_FaultServer::control_plane; - +use phoenix_api_policy_fault_server::control_plane; use phoenix_common::engine::datapath::message::{ EngineRxMessage, EngineTxMessage, RpcMessageGeneral, }; +use phoenix_common::engine::datapath::meta_pool::MetaBufferPool; use phoenix_common::engine::datapath::node::DataPathNode; use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; @@ -21,7 +22,7 @@ use phoenix_common::impl_vertex_for_engine; use phoenix_common::log; use phoenix_common::module::Version; -use phoenix_common::engine::datapath::RpcMessageTx; +use phoenix_common::engine::datapath::{RpcMessageRx, RpcMessageTx}; use phoenix_common::storage::{ResourceCollection, SharedStorage}; use super::DatapathError; @@ -44,6 +45,7 @@ pub(crate) struct FaultServerEngine { pub(crate) node: DataPathNode, pub(crate) indicator: Indicator, pub(crate) config: FaultServerConfig, + pub(crate) meta_buf_pool: MetaBufferPool, pub(crate) var_probability: f32, } @@ -102,6 +104,7 @@ impl Decompose for FaultServerEngine { let engine = *self; let mut collections = ResourceCollection::with_capacity(4); collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("meta_buf_pool".to_string(), Box::new(engine.meta_buf_pool)); (collections, engine.node) } } @@ -117,12 +120,18 @@ impl FaultServerEngine { .unwrap() .downcast::() .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let meta_buf_pool = *local + .remove("meta_buf_pool") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; let var_probability = 0.01; let engine = FaultServerEngine { node, - indicator: DeFaultServer::deFaultServer(), + indicator: Default::default(), config, + meta_buf_pool, var_probability, }; Ok(engine) @@ -153,78 +162,79 @@ fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { return req; } +/// Copy the RPC request to a private heap and returns the request. +#[inline] +fn materialize_rx(msg: &RpcMessageRx) -> Box { + let req_ptr = Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_ref() }; + // returns a private_req + Box::new(req.clone()) +} + impl FaultServerEngine { fn check_input_queue(&mut self) -> Result { use phoenix_common::engine::datapath::TryRecvError; match self.tx_inputs()[0].try_recv() { Ok(msg) => { - match msg { - EngineTxMessage::RpcMessage(msg) => { - let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; - let mut input = Vec::new(); - input.push(msg); - let output: Vec<_> = input - .iter() - .map(|msg| { - let rpc_message = materialize_nocopy(&msg); - let conn_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.conn_id; - let call_id = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }.call_id; - let rpc_id = RpcId::new(conn_id, call_id); - if rand::random::() < self.var_probability { - let error = EngineRxMessage::Ack( - rpc_id, - TransportStatus::Error(unsafe { - NonZeroU32::new_unchecked(403) - }), - ); - RpcMessageGeneral::RxMessage(error) - } else { - let raw_ptr: *const hello::HelloRequest = rpc_message; - let new_msg = RpcMessageTx { - meta_buf_ptr: msg.meta_buf_ptr.clone(), - addr_backend: raw_ptr.addr(), - }; - RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage( - new_msg, - )) - } - }) - .collect(); - - for msg in output { - match msg { - RpcMessageGeneral::TxMessage(msg) => { - self.tx_outputs()[0].send(msg)?; - } - RpcMessageGeneral::RxMessage(msg) => { - self.rx_outputs()[0].send(msg)?; - } - _ => {} - } - } - } - m => self.tx_outputs()[0].send(m)?, - } + self.tx_outputs()[0].send(msg)?; return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} - Err(TryRecvError::Disconnected) => { - return Ok(Status::Disconnected); - } + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), } match self.rx_inputs()[0].try_recv() { - Ok(msg) => { - match msg { + Ok(m) => { + match m { EngineRxMessage::Ack(rpc_id, status) => { - // todo - self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + if let Ok(()) = self.meta_buf_pool.release(rpc_id) { + // log::info!( + // "Access denied ack received, rpc_id: {:?} metabuf released", + // rpc_id + // ); + } else { + // log::info!("release failed!: {:?}", rpc_id); + self.rx_outputs()[0].send(m)?; + } } EngineRxMessage::RpcMessage(msg) => { - self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + let private_req = materialize_rx(&msg); + if rand::random::() < self.var_probability { + // We need to copy meta, add it to meta_buf_pool, and send it as the tx msg + // Is there better way to do this and avoid unsafe? + let mut meta = unsafe { msg.meta.as_ref().clone() }; + meta.status_code = StatusCode::AccessDenied; + let mut meta_ptr = self + .meta_buf_pool + .obtain(RpcId(meta.conn_id, meta.call_id)) + .expect("meta_buf_pool is full"); + unsafe { + meta_ptr.as_meta_ptr().write(meta); + meta_ptr.0.as_mut().num_sge = 0; + meta_ptr.0.as_mut().value_len = 0; + } + let rpc_msg = RpcMessageTx { + meta_buf_ptr: meta_ptr, + addr_backend: 0, + }; + let new_msg = EngineTxMessage::RpcMessage(rpc_msg); + self.tx_outputs()[0] + .send(new_msg) + .expect("send new message error"); + let msg_call_ids = + [meta.call_id, meta.call_id, meta.call_id, meta.call_id]; + self.tx_outputs()[0].send(EngineTxMessage::ReclaimRecvBuf( + meta.conn_id, + msg_call_ids, + ))?; + } else { + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + } + EngineRxMessage::RecvError(_, _) => { + self.rx_outputs()[0].send(m)?; } - m => self.rx_outputs()[0].send(m)?, } return Ok(Progress(1)); } diff --git a/experimental/mrpc/plugin/policy/fault-server/src/module.rs b/experimental/mrpc/plugin/policy/fault-server/src/module.rs index f986450f..a950423e 100644 --- a/experimental/mrpc/plugin/policy/fault-server/src/module.rs +++ b/experimental/mrpc/plugin/policy/fault-server/src/module.rs @@ -1,14 +1,14 @@ use anyhow::{bail, Result}; use nix::unistd::Pid; +use super::engine::FaultServerEngine; +use crate::config::{create_log_file, FaultServerConfig}; use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::meta_pool::MetaBufferPool; use phoenix_common::engine::datapath::DataPathNode; use phoenix_common::engine::{Engine, EngineType}; use phoenix_common::storage::ResourceCollection; -use super::engine::FaultServerEngine; -use crate::config::{create_log_file, FaultServerConfig}; - use chrono::prelude::*; use itertools::iproduct; use rand::Rng; @@ -25,11 +25,12 @@ impl FaultServerEngineBuilder { // TODO! LogFile fn build(self) -> Result { let var_probability = 0.01; - + const META_BUFFER_POOL_CAP: usize = 128; Ok(FaultServerEngine { node: self.node, - indicator: DeFaultServer::deFaultServer(), + indicator: Default::default(), config: self.config, + meta_buf_pool: MetaBufferPool::new(META_BUFFER_POOL_CAP), var_probability, }) } @@ -40,8 +41,8 @@ pub struct FaultServerAddon { } impl FaultServerAddon { - pub const FaultServer_ENGINE: EngineType = EngineType("FaultServerEngine"); - pub const ENGINES: &'static [EngineType] = &[FaultServerAddon::FaultServer_ENGINE]; + pub const FAULT_SERVER_ENGINE: EngineType = EngineType("FaultServerEngine"); + pub const ENGINES: &'static [EngineType] = &[FaultServerAddon::FAULT_SERVER_ENGINE]; } impl FaultServerAddon { @@ -80,7 +81,7 @@ impl PhoenixAddon for FaultServerAddon { _pid: Pid, node: DataPathNode, ) -> Result> { - if ty != FaultServerAddon::FaultServer_ENGINE { + if ty != FaultServerAddon::FAULT_SERVER_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -96,7 +97,7 @@ impl PhoenixAddon for FaultServerAddon { node: DataPathNode, prev_version: Version, ) -> Result> { - if ty != FaultServerAddon::FaultServer_ENGINE { + if ty != FaultServerAddon::FAULT_SERVER_ENGINE { bail!("invalid engine type {:?}", ty) } diff --git a/experimental/mrpc/plugin/policy/logging-server/Cargo.toml b/experimental/mrpc/plugin/policy/logging-server/Cargo.toml index e058ccd2..d510ca4d 100644 --- a/experimental/mrpc/plugin/policy/logging-server/Cargo.toml +++ b/experimental/mrpc/plugin/policy/logging-server/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "phoenix-LoggingServer" +name = "phoenix-logging-server" version = "0.1.0" edition = "2021" @@ -7,7 +7,7 @@ edition = "2021" [dependencies] phoenix_common.workspace = true -phoenix-api-policy-LoggingServer.workspace = true +phoenix-api-policy-logging-server.workspace = true mrpc-marshal.workspace = true mrpc-derive.workspace = true shm.workspace = true diff --git a/experimental/mrpc/plugin/policy/logging-server/src/config.rs b/experimental/mrpc/plugin/policy/logging-server/src/config.rs index 5ba0472b..f6b8c2f9 100644 --- a/experimental/mrpc/plugin/policy/logging-server/src/config.rs +++ b/experimental/mrpc/plugin/policy/logging-server/src/config.rs @@ -6,7 +6,7 @@ use chrono::{Datelike, Timelike, Utc}; use phoenix_common::log; use serde::{Deserialize, Serialize}; -/// currently, LoggingServer engine does not need a config +/// currently, logging engine does not need a config #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct LoggingServerConfig {} @@ -21,7 +21,7 @@ impl LoggingServerConfig { /// Create a log file in `/tmp/phoenix/log` /// This function will be called every time -/// a LoggingServer engine is started or restored +/// a logging engine is started or restored pub fn create_log_file() -> std::fs::File { std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); let now = Utc::now(); @@ -34,7 +34,7 @@ pub fn create_log_file() -> std::fs::File { now.minute(), now.second() ); - let file_name = format!("/tmp/phoenix/log/LoggingServer_engine_{}.log", date_string); + let file_name = format!("/tmp/phoenix/log/logging_engine_{}.log", date_string); log::info!("create log file {}", file_name); let log_file = std::fs::File::create(file_name).expect("create file failed"); log_file diff --git a/experimental/mrpc/plugin/policy/logging-server/src/engine.rs b/experimental/mrpc/plugin/policy/logging-server/src/engine.rs index 0b219a85..a1f4fbde 100644 --- a/experimental/mrpc/plugin/policy/logging-server/src/engine.rs +++ b/experimental/mrpc/plugin/policy/logging-server/src/engine.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use chrono::Utc; use futures::future::BoxFuture; -use phoenix_api_policy_LoggingServer::control_plane; +use phoenix_api_policy_logging_server::control_plane; use phoenix_common::engine::datapath::RpcMessageTx; use std::io::Write; use std::os::unix::ucred::UCred; @@ -24,7 +24,7 @@ pub mod hello { include!("proto.rs"); } -/// The internal state of an LoggingServer engine, +/// The internal state of an logging engine, /// it contains some template fields like `node`, `indicator`, /// a config field, in that case `LoggingServerConfig` /// and other custome fields like `log_file @@ -157,81 +157,49 @@ fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { impl LoggingServerEngine { /// main logic about handling rx & tx input messages - /// note that a LoggingServer engine can be deployed in client-side or server-side + /// note that a logging engine can be deployed in client-side or server-side fn check_input_queue(&mut self) -> Result { use phoenix_common::engine::datapath::TryRecvError; - // tx logic - // For server it is `On-Response` logic, when sending response to network - // For client it is `On-Request` logic, when sending request to network match self.tx_inputs()[0].try_recv() { Ok(msg) => { - match msg { - // we care only log RPCs - // other types like ACK should not be logged since they are not - // ACKs between Client/Server, but communication between engines - // "Real" ACKs are logged in rx logic - EngineTxMessage::RpcMessage(msg) => { - // we get the metadata of RPC from the shared memory - let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; - let rpc_message = materialize_nocopy(&msg); + self.tx_outputs()[0].send(msg)?; + return Ok(Progress(1)); + } + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), + } + + match self.rx_inputs()[0].try_recv() { + Ok(m) => { + match m { + EngineRxMessage::Ack(rpc_id, _status) => { + self.rx_outputs()[0].send(m)?; + } + EngineRxMessage::RpcMessage(msg) => { + let meta_ref = unsafe { msg.meta.as_ref() }; // write the metadata into the file // since meta_ref implements Debug, we can use {:?} // rather than manully parse the metadata struct write!( self.log_file, - "{}{}{}{}{}\n", + "{}{}{}{}\n", Utc::now(), format!("{:?}", meta_ref.msg_type), format!("{:?}", meta_ref.conn_id), format!("{:?}", meta_ref.conn_id), - format!("{}", String::from_utf8_lossy(&rpc_message.name)), ) .unwrap(); - - // after LoggingServer, we forward the message to the next engine - self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; - } - // if received message is not RPC, we simple forward it - m => self.tx_outputs()[0].send(m)?, - } - return Ok(Progress(1)); - } - Err(TryRecvError::Empty) => {} - Err(TryRecvError::Disconnected) => { - return Ok(Status::Disconnected); - } - } - - // tx logic - // For server it is `On-Request` logic, when recving request from network - // For client it is `On-Response` logic, when recving response from network - match self.rx_inputs()[0].try_recv() { - Ok(msg) => { - match msg { - // ACK means that - // If I am client: server received my request - // If I am server: client recevied my response - EngineRxMessage::Ack(rpc_id, status) => { - // log the info to the file - // forward the message - self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; - } - EngineRxMessage::RpcMessage(msg) => { - // forward the message - // again, this RpcMessage is not the application-level rpc - // so we don log them self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; } - // forward other unknown msg - m => self.rx_outputs()[0].send(m)?, + EngineRxMessage::RecvError(_, _) => { + self.rx_outputs()[0].send(m)?; + } } return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} - Err(TryRecvError::Disconnected) => { - return Ok(Status::Disconnected); - } + Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), } Ok(Progress(0)) diff --git a/experimental/mrpc/plugin/policy/logging-server/src/lib.rs b/experimental/mrpc/plugin/policy/logging-server/src/lib.rs index d036b86a..cfcbc595 100644 --- a/experimental/mrpc/plugin/policy/logging-server/src/lib.rs +++ b/experimental/mrpc/plugin/policy/logging-server/src/lib.rs @@ -1,5 +1,5 @@ //! template file for export - +#![feature(ptr_internals)] #![feature(peer_credentials_unix_socket)] use thiserror::Error; diff --git a/experimental/mrpc/plugin/policy/logging-server/src/module.rs b/experimental/mrpc/plugin/policy/logging-server/src/module.rs index 11fd6475..31fd42fb 100644 --- a/experimental/mrpc/plugin/policy/logging-server/src/module.rs +++ b/experimental/mrpc/plugin/policy/logging-server/src/module.rs @@ -39,8 +39,8 @@ pub struct LoggingServerAddon { } impl LoggingServerAddon { - pub const LoggingServer_ENGINE: EngineType = EngineType("LoggingServerEngine"); - pub const ENGINES: &'static [EngineType] = &[LoggingServerAddon::LoggingServer_ENGINE]; + pub const LOGGING_ENGINE: EngineType = EngineType("LoggingServerEngine"); + pub const ENGINES: &'static [EngineType] = &[LoggingServerAddon::LOGGING_ENGINE]; } impl LoggingServerAddon { @@ -79,7 +79,7 @@ impl PhoenixAddon for LoggingServerAddon { _pid: Pid, node: DataPathNode, ) -> Result> { - if ty != LoggingServerAddon::LoggingServer_ENGINE { + if ty != LoggingServerAddon::LOGGING_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -95,7 +95,7 @@ impl PhoenixAddon for LoggingServerAddon { node: DataPathNode, prev_version: Version, ) -> Result> { - if ty != LoggingServerAddon::LoggingServer_ENGINE { + if ty != LoggingServerAddon::LOGGING_ENGINE { bail!("invalid engine type {:?}", ty) } diff --git a/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml b/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml index b5118932..560932f9 100644 --- a/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml +++ b/experimental/mrpc/plugin/policy/metrics-server/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "phoenix-metrics" +name = "phoenix-metrics-server" version = "0.1.0" edition = "2021" @@ -7,7 +7,7 @@ edition = "2021" [dependencies] -phoenix-api-policy-metrics.workspace = true +phoenix-api-policy-metrics-server.workspace = true mrpc-marshal.workspace = true mrpc-derive.workspace = true diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs b/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs index 138fef39..22f6ea1a 100644 --- a/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs +++ b/experimental/mrpc/plugin/policy/metrics-server/src/engine.rs @@ -9,7 +9,7 @@ use fnv::FnvHashMap as HashMap; use futures::future::BoxFuture; use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; -use phoenix_api_policy_MetricsServer::control_plane; +use phoenix_api_policy_metrics_server::control_plane; use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; use phoenix_common::engine::datapath::node::DataPathNode; @@ -156,7 +156,20 @@ impl MetricsServerEngine { match self.tx_inputs()[0].try_recv() { Ok(msg) => { - self.tx_outputs()[0].send(msg)?; + match msg { + EngineTxMessage::RpcMessage(msg) => { + let meta = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; + if meta.status_code == StatusCode::Success { + self.num_succ += 1; + } else { + self.num_rej += 1; + } + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; + } + m => { + self.tx_outputs()[0].send(m)?; + } + } return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} @@ -166,20 +179,7 @@ impl MetricsServerEngine { // forward all rx msgs match self.rx_inputs()[0].try_recv() { Ok(m) => { - match m { - EngineRxMessage::RpcMessage(msg) => { - let meta = unsafe { &*msg.meta.as_ptr() }; - if meta.status_code == StatusCode::Success { - self.num_succ += 1; - } else { - self.num_rej += 1; - } - self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; - } - m => { - self.rx_outputs()[0].send(m)?; - } - }; + self.rx_outputs()[0].send(m)?; return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} diff --git a/experimental/mrpc/plugin/policy/metrics-server/src/module.rs b/experimental/mrpc/plugin/policy/metrics-server/src/module.rs index d1225bce..e20b9246 100644 --- a/experimental/mrpc/plugin/policy/metrics-server/src/module.rs +++ b/experimental/mrpc/plugin/policy/metrics-server/src/module.rs @@ -36,8 +36,8 @@ pub struct MetricsServerAddon { } impl MetricsServerAddon { - pub const MetricsServer_ENGINE: EngineType = EngineType("MetricsServerEngine"); - pub const ENGINES: &'static [EngineType] = &[MetricsServerAddon::MetricsServer_ENGINE]; + pub const METRICS_ENGINE: EngineType = EngineType("MetricsServerEngine"); + pub const ENGINES: &'static [EngineType] = &[MetricsServerAddon::METRICS_ENGINE]; } impl MetricsServerAddon { @@ -76,7 +76,7 @@ impl PhoenixAddon for MetricsServerAddon { _pid: Pid, node: DataPathNode, ) -> Result> { - if ty != MetricsServerAddon::MetricsServer_ENGINE { + if ty != MetricsServerAddon::METRICS_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -92,7 +92,7 @@ impl PhoenixAddon for MetricsServerAddon { node: DataPathNode, prev_version: Version, ) -> Result> { - if ty != MetricsServerAddon::MetricsServer_ENGINE { + if ty != MetricsServerAddon::METRICS_ENGINE { bail!("invalid engine type {:?}", ty) } diff --git a/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml b/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml index da4953c0..a6552545 100644 --- a/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml +++ b/experimental/mrpc/plugin/policy/mutation-server/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "phoenix-mutation" +name = "phoenix-mutation-server" version = "0.1.0" edition = "2021" @@ -7,7 +7,7 @@ edition = "2021" [dependencies] -phoenix-api-policy-mutation.workspace = true +phoenix-api-policy-mutation-server.workspace = true mrpc-marshal.workspace = true mrpc-derive.workspace = true diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs b/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs index eadc2dbc..97c6bbdb 100644 --- a/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs +++ b/experimental/mrpc/plugin/policy/mutation-server/src/engine.rs @@ -9,10 +9,11 @@ use fnv::FnvHashMap as HashMap; use futures::future::BoxFuture; use phoenix_api::rpc::{RpcId, TransportStatus}; -use phoenix_api_policy_MutationServer::control_plane; +use phoenix_api_policy_mutation_server::control_plane; use phoenix_common::engine::datapath::message::{EngineRxMessage, EngineTxMessage, RpcMessageTx}; use phoenix_common::engine::datapath::node::DataPathNode; +use phoenix_common::engine::datapath::RpcMessageRx; use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; use phoenix_common::envelop::ResourceDowncast; use phoenix_common::impl_vertex_for_engine; @@ -147,13 +148,11 @@ impl MutationServerEngine { } } -/// Copy the RPC request to a private heap and returns the request. #[inline] -fn materialize(msg: &RpcMessageTx) -> Box { - let req_ptr = Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); - let req = unsafe { req_ptr.as_ref() }; - // returns a private_req - Box::new(req.clone()) +fn materialize_nocopy(msg: &RpcMessageRx) -> &mut hello::HelloRequest { + let req_ptr = msg.addr_backend as *mut hello::HelloRequest; + let req = unsafe { req_ptr.as_mut().unwrap() }; + return req; } impl MutationServerEngine { @@ -162,28 +161,30 @@ impl MutationServerEngine { match self.tx_inputs()[0].try_recv() { Ok(msg) => { - match msg { - EngineTxMessage::RpcMessage(msg) => { - let mut req_ptr = - Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); - let req = unsafe { req_ptr.as_mut() }; - for i in 0..req.name.len() { - req.name[i] = 'a' as u8; - } - self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(msg))?; - } - m => self.tx_outputs()[0].send(m)?, - } + self.tx_outputs()[0].send(msg)?; return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), } - // forward all rx msgs match self.rx_inputs()[0].try_recv() { Ok(m) => { - self.rx_outputs()[0].send(m)?; + match m { + EngineRxMessage::Ack(rpc_id, _status) => { + self.rx_outputs()[0].send(m)?; + } + EngineRxMessage::RpcMessage(msg) => { + let mut req = materialize_nocopy(&msg); + for i in 0..req.name.len() { + req.name[i] = 'a' as u8; + } + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + EngineRxMessage::RecvError(_, _) => { + self.rx_outputs()[0].send(m)?; + } + } return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} diff --git a/experimental/mrpc/plugin/policy/mutation-server/src/module.rs b/experimental/mrpc/plugin/policy/mutation-server/src/module.rs index d8683ad1..9f60e8aa 100644 --- a/experimental/mrpc/plugin/policy/mutation-server/src/module.rs +++ b/experimental/mrpc/plugin/policy/mutation-server/src/module.rs @@ -35,8 +35,8 @@ pub struct MutationServerAddon { } impl MutationServerAddon { - pub const MutationServer_ENGINE: EngineType = EngineType("MutationServerEngine"); - pub const ENGINES: &'static [EngineType] = &[MutationServerAddon::MutationServer_ENGINE]; + pub const MUTATION_ENGINE: EngineType = EngineType("MutationServerEngine"); + pub const ENGINES: &'static [EngineType] = &[MutationServerAddon::MUTATION_ENGINE]; } impl MutationServerAddon { @@ -75,7 +75,7 @@ impl PhoenixAddon for MutationServerAddon { _pid: Pid, node: DataPathNode, ) -> Result> { - if ty != MutationServerAddon::MutationServer_ENGINE { + if ty != MutationServerAddon::MUTATION_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -91,7 +91,7 @@ impl PhoenixAddon for MutationServerAddon { node: DataPathNode, prev_version: Version, ) -> Result> { - if ty != MutationServerAddon::MutationServer_ENGINE { + if ty != MutationServerAddon::MUTATION_ENGINE { bail!("invalid engine type {:?}", ty) } diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml b/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml index 4b592492..0f2a1eaa 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/Cargo.toml @@ -1,5 +1,6 @@ + [package] -name = "phoenix-ratelimit-drop" +name = "phoenix-ratelimit-drop-server" version = "0.1.0" edition = "2021" @@ -7,7 +8,11 @@ edition = "2021" [dependencies] phoenix_common.workspace = true -phoenix-api-policy-ratelimit-drop.workspace = true +phoenix-api-policy-ratelimit-drop-server.workspace = true +mrpc-marshal.workspace = true +mrpc-derive.workspace = true +shm.workspace = true +phoenix-api = { workspace = true, features = ["mrpc"] } futures.workspace = true minstant.workspace = true @@ -18,9 +23,6 @@ anyhow.workspace = true nix.workspace = true toml = { workspace = true, features = ["preserve_order"] } bincode.workspace = true -mrpc-marshal.workspace = true -mrpc-derive.workspace = true -shm.workspace = true -phoenix-api = { workspace = true, features = ["mrpc"] } chrono.workspace = true itertools.workspace = true +rand.workspace = true diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs index 2d4bdeb0..086114ea 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/config.rs @@ -1,7 +1,14 @@ +use chrono::{Datelike, Timelike, Utc}; +use phoenix_common::log; use serde::{Deserialize, Serialize}; +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(deny_unknown_fields)] + pub struct RateLimitDropServerConfig { pub requests_per_sec: u64, pub bucket_size: u64, @@ -22,3 +29,20 @@ impl RateLimitDropServerConfig { Ok(config) } } +pub fn create_log_file() -> std::fs::File { + std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); + let now = Utc::now(); + let date_string = format!( + "{}-{}-{}-{}-{}-{}", + now.year(), + now.month(), + now.day(), + now.hour(), + now.minute(), + now.second() + ); + let file_name = format!("/tmp/phoenix/log/logging_engine_{}.log", date_string); + ///log::info!("create log file {}", file_name); + let log_file = std::fs::File::create(file_name).expect("create file failed"); + log_file +} diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs index b95b210d..cb5ecea9 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/engine.rs @@ -1,24 +1,37 @@ -use std::collections::VecDeque; -use std::os::unix::ucred::UCred; -use std::pin::Pin; - -use super::DatapathError; -use crate::config::RateLimitDropServerConfig; use anyhow::{anyhow, Result}; use futures::future::BoxFuture; use minstant::Instant; -use phoenix_api::rpc::{RpcId, TransportStatus}; -use phoenix_api_policy_ratelimit_drop::control_plane; -use phoenix_common::engine::datapath::message::{EngineTxMessage, RpcMessageGeneral, RpcMessageTx}; +use phoenix_api::rpc::{RpcId, StatusCode, TransportStatus}; +use std::fmt; +use std::fs::File; +use std::io::Write; +use std::num::NonZeroU32; +use std::os::unix::ucred::UCred; +use std::pin::Pin; +use std::ptr::Unique; + +use phoenix_api_policy_ratelimit_drop_server::control_plane; +use phoenix_common::engine::datapath::message::{ + EngineRxMessage, EngineTxMessage, RpcMessageGeneral, +}; +use phoenix_common::engine::datapath::meta_pool::MetaBufferPool; + use phoenix_common::engine::datapath::node::DataPathNode; -use phoenix_common::engine::datapath::EngineRxMessage; use phoenix_common::engine::{future, Decompose, Engine, EngineResult, Indicator, Vertex}; use phoenix_common::envelop::ResourceDowncast; use phoenix_common::impl_vertex_for_engine; use phoenix_common::log; use phoenix_common::module::Version; + +use phoenix_common::engine::datapath::{RpcMessageRx, RpcMessageTx}; use phoenix_common::storage::{ResourceCollection, SharedStorage}; -use std::num::NonZeroU32; + +use super::DatapathError; +use crate::config::{create_log_file, RateLimitDropServerConfig}; + +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; pub mod hello { include!("proto.rs"); @@ -39,6 +52,8 @@ pub(crate) struct RateLimitDropServerEngine { // pub(crate) filter: FnvHashSet, // Number of tokens to add for each seconds. pub(crate) config: RateLimitDropServerConfig, + pub(crate) meta_buf_pool: MetaBufferPool, + // The most recent timestamp we add the token to the bucket. pub(crate) last_ts: Instant, // The number of available tokens in the token bucket algorithm. @@ -87,12 +102,11 @@ impl_vertex_for_engine!(RateLimitDropServerEngine, node); impl Decompose for RateLimitDropServerEngine { fn flush(&mut self) -> Result { let mut work = 0; - while !self.tx_inputs()[0].is_empty() { + while !self.tx_inputs()[0].is_empty() || !self.rx_inputs()[0].is_empty() { if let Progress(n) = self.check_input_queue()? { work += n; } } - Ok(work) } @@ -102,9 +116,9 @@ impl Decompose for RateLimitDropServerEngine { _global: &mut ResourceCollection, ) -> (ResourceCollection, DataPathNode) { let engine = *self; - let mut collections = ResourceCollection::with_capacity(4); collections.insert("config".to_string(), Box::new(engine.config)); + collections.insert("meta_buf_pool".to_string(), Box::new(engine.meta_buf_pool)); collections.insert("last_ts".to_string(), Box::new(engine.last_ts)); collections.insert("num_tokens".to_string(), Box::new(engine.num_tokens)); (collections, engine.node) @@ -122,6 +136,11 @@ impl RateLimitDropServerEngine { .unwrap() .downcast::() .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; + let meta_buf_pool = *local + .remove("meta_buf_pool") + .unwrap() + .downcast::() + .map_err(|x| anyhow!("fail to downcast, type_name={:?}", x.type_name()))?; let last_ts: Instant = *local .remove("last_ts") .unwrap() @@ -139,6 +158,7 @@ impl RateLimitDropServerEngine { config, last_ts, num_tokens, + meta_buf_pool, }; Ok(engine) } @@ -148,7 +168,6 @@ impl RateLimitDropServerEngine { async fn mainloop(&mut self) -> EngineResult { loop { let mut work = 0; - // check input queue, ~100ns loop { match self.check_input_queue()? { Progress(0) => break, @@ -156,10 +175,7 @@ impl RateLimitDropServerEngine { Status::Disconnected => return Ok(()), } } - - // If there's pending receives, there will always be future work to do. self.indicator.set_nwork(work); - future::yield_now().await; } } @@ -168,7 +184,6 @@ impl RateLimitDropServerEngine { fn current_timestamp() -> Instant { Instant::now() } - #[inline] fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { let req_ptr = msg.addr_backend as *mut hello::HelloRequest; @@ -176,77 +191,78 @@ fn materialize_nocopy(msg: &RpcMessageTx) -> &hello::HelloRequest { return req; } +/// Copy the RPC request to a private heap and returns the request. +#[inline] +fn materialize_rx(msg: &RpcMessageRx) -> Box { + let req_ptr = Unique::new(msg.addr_backend as *mut hello::HelloRequest).unwrap(); + let req = unsafe { req_ptr.as_ref() }; + // returns a private_req + Box::new(req.clone()) +} + impl RateLimitDropServerEngine { fn check_input_queue(&mut self) -> Result { use phoenix_common::engine::datapath::TryRecvError; match self.tx_inputs()[0].try_recv() { Ok(msg) => { - match msg { - EngineTxMessage::RpcMessage(msg) => { - let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; - let mut input = Vec::new(); - input.push(msg); - self.num_tokens = self.num_tokens - + (current_timestamp() - self.last_ts).as_secs_f64() - * self.config.requests_per_sec as f64; - self.last_ts = current_timestamp(); - log::debug!("num_tokens: {}", self.num_tokens); - let limit = std::cmp::min(input.len() as i64, self.num_tokens as i64); - self.num_tokens = self.num_tokens - limit as f64; - - let output = input.iter().enumerate().map(|(index, req)| { - let rpc_message = materialize_nocopy(&req); - let conn_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.conn_id; - let call_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.call_id; - let rpc_id = RpcId::new(conn_id, call_id); - if index < limit as usize { - let raw_ptr: *const hello::HelloRequest = rpc_message; - let new_msg = RpcMessageTx { - meta_buf_ptr: req.meta_buf_ptr.clone(), - addr_backend: req.addr_backend, - }; - RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage(new_msg)) - } else { - let error = EngineRxMessage::Ack( - rpc_id, - TransportStatus::Error(unsafe { - NonZeroU32::new_unchecked(403) - }), - ); - RpcMessageGeneral::RxMessage(error) - } - }); - for msg in output { - match msg { - RpcMessageGeneral::TxMessage(msg) => { - self.tx_outputs()[0].send(msg)?; - } - RpcMessageGeneral::RxMessage(msg) => { - self.rx_outputs()[0].send(msg)?; - } - _ => {} - } - } - } - m => self.tx_outputs()[0].send(m)?, - } + self.tx_outputs()[0].send(msg)?; return Ok(Progress(1)); } Err(TryRecvError::Empty) => {} Err(TryRecvError::Disconnected) => return Ok(Status::Disconnected), } + match self.rx_inputs()[0].try_recv() { - Ok(msg) => { - match msg { + Ok(m) => { + match m { EngineRxMessage::Ack(rpc_id, status) => { - // todo - self.rx_outputs()[0].send(EngineRxMessage::Ack(rpc_id, status))?; + if let Ok(()) = self.meta_buf_pool.release(rpc_id) { + } else { + self.rx_outputs()[0].send(m)?; + } } EngineRxMessage::RpcMessage(msg) => { - self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + self.num_tokens = self.num_tokens + + (current_timestamp() - self.last_ts).as_secs_f64() + * self.config.requests_per_sec as f64; + self.last_ts = current_timestamp(); + if self.num_tokens < 1.0 { + // We need to copy meta, add it to meta_buf_pool, and send it as the tx msg + // Is there better way to do this and avoid unsafe? + let mut meta = unsafe { msg.meta.as_ref().clone() }; + meta.status_code = StatusCode::AccessDenied; + let mut meta_ptr = self + .meta_buf_pool + .obtain(RpcId(meta.conn_id, meta.call_id)) + .expect("meta_buf_pool is full"); + unsafe { + meta_ptr.as_meta_ptr().write(meta); + meta_ptr.0.as_mut().num_sge = 0; + meta_ptr.0.as_mut().value_len = 0; + } + let rpc_msg = RpcMessageTx { + meta_buf_ptr: meta_ptr, + addr_backend: 0, + }; + let new_msg = EngineTxMessage::RpcMessage(rpc_msg); + self.tx_outputs()[0] + .send(new_msg) + .expect("send new message error"); + let msg_call_ids = + [meta.call_id, meta.call_id, meta.call_id, meta.call_id]; + self.tx_outputs()[0].send(EngineTxMessage::ReclaimRecvBuf( + meta.conn_id, + msg_call_ids, + ))?; + } else { + self.num_tokens = self.num_tokens - 1.0; + self.rx_outputs()[0].send(EngineRxMessage::RpcMessage(msg))?; + } + } + EngineRxMessage::RecvError(_, _) => { + self.rx_outputs()[0].send(m)?; } - m => self.rx_outputs()[0].send(m)?, } return Ok(Progress(1)); } diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs index b77ef8bd..15fd5311 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/lib.rs @@ -1,7 +1,12 @@ #![feature(peer_credentials_unix_socket)] - +#![feature(ptr_internals)] +#![feature(strict_provenance)] use thiserror::Error; +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; + pub use phoenix_common::{InitFnResult, PhoenixAddon}; pub mod config; diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs index baa16ebb..244bdff9 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs +++ b/experimental/mrpc/plugin/policy/ratelimit-drop-server/src/module.rs @@ -1,16 +1,18 @@ -use std::collections::VecDeque; - use anyhow::{bail, Result}; use minstant::Instant; use nix::unistd::Pid; +use super::engine::RateLimitDropServerEngine; +use crate::config::{create_log_file, RateLimitDropServerConfig}; use phoenix_common::addon::{PhoenixAddon, Version}; +use phoenix_common::engine::datapath::meta_pool::{MetaBufferPool, META_BUFFER_SIZE}; use phoenix_common::engine::datapath::DataPathNode; use phoenix_common::engine::{Engine, EngineType}; use phoenix_common::storage::ResourceCollection; -use super::engine::RateLimitDropServerEngine; -use crate::config::RateLimitDropServerConfig; +use chrono::prelude::*; +use itertools::iproduct; +use rand::Rng; pub(crate) struct RateLimitDropServerEngineBuilder { node: DataPathNode, @@ -21,12 +23,14 @@ impl RateLimitDropServerEngineBuilder { fn new(node: DataPathNode, config: RateLimitDropServerConfig) -> Self { RateLimitDropServerEngineBuilder { node, config } } - + // TODO! LogFile fn build(self) -> Result { + let META_BUFFER_POOL_CAP = 200; Ok(RateLimitDropServerEngine { node: self.node, indicator: Default::default(), config: self.config, + meta_buf_pool: MetaBufferPool::new(META_BUFFER_POOL_CAP), last_ts: Instant::now(), num_tokens: self.config.bucket_size as _, }) @@ -38,8 +42,9 @@ pub struct RateLimitDropServerAddon { } impl RateLimitDropServerAddon { - pub const RATE_LIMIT_DROP_ENGINE: EngineType = EngineType("RateLimitDropServerEngine"); - pub const ENGINES: &'static [EngineType] = &[RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE]; + pub const RATELIMIT_DROP_SERVER_ENGINE: EngineType = EngineType("RateLimitDropServerEngine"); + pub const ENGINES: &'static [EngineType] = + &[RateLimitDropServerAddon::RATELIMIT_DROP_SERVER_ENGINE]; } impl RateLimitDropServerAddon { @@ -78,7 +83,7 @@ impl PhoenixAddon for RateLimitDropServerAddon { _pid: Pid, node: DataPathNode, ) -> Result> { - if ty != RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE { + if ty != RateLimitDropServerAddon::RATELIMIT_DROP_SERVER_ENGINE { bail!("invalid engine type {:?}", ty) } @@ -94,7 +99,7 @@ impl PhoenixAddon for RateLimitDropServerAddon { node: DataPathNode, prev_version: Version, ) -> Result> { - if ty != RateLimitDropServerAddon::RATE_LIMIT_DROP_ENGINE { + if ty != RateLimitDropServerAddon::RATELIMIT_DROP_SERVER_ENGINE { bail!("invalid engine type {:?}", ty) } From f1b48ef0d1e7f9494725fde8f5446816a509d0ec Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 3 Dec 2023 03:40:48 +0000 Subject: [PATCH 16/21] scripts --- eval/policy/fault-server/attach.toml | 33 +++++++++++ eval/policy/fault-server/collect.py | 47 +++++++++++++++ eval/policy/fault-server/config.toml | 9 +++ eval/policy/fault-server/detach.toml | 4 ++ .../fault-server/rpc_bench_tput_32b.toml | 15 +++++ eval/policy/fault-server/start_traffic.sh | 29 ++++++++++ eval/policy/logging-server/README.md | 4 ++ eval/policy/logging-server/attach.toml | 31 ++++++++++ eval/policy/logging-server/collect.py | 33 +++++++++++ eval/policy/logging-server/config.toml | 9 +++ eval/policy/logging-server/detach.toml | 4 ++ .../logging-server/rpc_bench_tput_32b.toml | 15 +++++ eval/policy/logging-server/run_policy.py | 58 +++++++++++++++++++ eval/policy/metrics-server/attach.toml | 33 +++++++++++ eval/policy/metrics-server/collect.py | 47 +++++++++++++++ eval/policy/metrics-server/config.toml | 9 +++ eval/policy/metrics-server/detach.toml | 4 ++ .../metrics-server/rpc_bench_tput_32b.toml | 15 +++++ eval/policy/metrics-server/start_traffic.sh | 29 ++++++++++ eval/policy/mutation-server/attach.toml | 31 ++++++++++ eval/policy/mutation-server/detach.toml | 6 ++ eval/policy/ratelimit-drop-server/attach.toml | 35 +++++++++++ eval/policy/ratelimit-drop-server/detach.toml | 4 ++ 23 files changed, 504 insertions(+) create mode 100644 eval/policy/fault-server/attach.toml create mode 100755 eval/policy/fault-server/collect.py create mode 100644 eval/policy/fault-server/config.toml create mode 100644 eval/policy/fault-server/detach.toml create mode 100644 eval/policy/fault-server/rpc_bench_tput_32b.toml create mode 100755 eval/policy/fault-server/start_traffic.sh create mode 100644 eval/policy/logging-server/README.md create mode 100644 eval/policy/logging-server/attach.toml create mode 100755 eval/policy/logging-server/collect.py create mode 100644 eval/policy/logging-server/config.toml create mode 100644 eval/policy/logging-server/detach.toml create mode 100644 eval/policy/logging-server/rpc_bench_tput_32b.toml create mode 100755 eval/policy/logging-server/run_policy.py create mode 100644 eval/policy/metrics-server/attach.toml create mode 100755 eval/policy/metrics-server/collect.py create mode 100644 eval/policy/metrics-server/config.toml create mode 100644 eval/policy/metrics-server/detach.toml create mode 100644 eval/policy/metrics-server/rpc_bench_tput_32b.toml create mode 100755 eval/policy/metrics-server/start_traffic.sh create mode 100644 eval/policy/mutation-server/attach.toml create mode 100644 eval/policy/mutation-server/detach.toml create mode 100644 eval/policy/ratelimit-drop-server/attach.toml create mode 100644 eval/policy/ratelimit-drop-server/detach.toml diff --git a/eval/policy/fault-server/attach.toml b/eval/policy/fault-server/attach.toml new file mode 100644 index 00000000..4dcca7ff --- /dev/null +++ b/eval/policy/fault-server/attach.toml @@ -0,0 +1,33 @@ +addon_engine = "FaultServerEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "FaultServerEngine", + 0, + 0, + ], + [ + "FaultServerEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "FaultServerEngine", + 0, + 0, + ], + [ + "FaultServerEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +''' diff --git a/eval/policy/fault-server/collect.py b/eval/policy/fault-server/collect.py new file mode 100755 index 00000000..009eec0d --- /dev/null +++ b/eval/policy/fault-server/collect.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from typing import List +import glob +import sys + +OD = "/tmp/mrpc-eval" +if len(sys.argv) >= 2: + OD = sys.argv[1] + + +def convert_msg_size(s: str) -> int: + if s.endswith('gb'): + return int(s[:-2]) * 1024 * 1024 * 1024 + if s.endswith('mb'): + return int(s[:-2]) * 1024 * 1024 + if s.endswith('kb'): + return int(s[:-2]) * 1024 + if s.endswith('b'): + return int(s[:-1]) + + raise ValueError(f"unknown input: {s}") + + +def get_rate(path: str) -> List[float]: + rates = [] + with open(path, 'r') as fin: + for line in fin: + words = line.strip().split(' ') + if words[-3] == 'rps,': + rate = float(words[-4]) + rates.append(rate) + return rates[1:] + + +def load_result(sol_before, sol_after, f: str): + # print(f) + rates = get_rate(f) + before = rates[5:25] + after = rates[-25:-5] + for r in before: + print(f'{round(r/1000,2)},{sol_before},w/o Fault') + for r in after: + print(f'{round(r/1000,2)},{sol_after},w/ Fault') + + +for f in glob.glob(OD+"/policy/fault/rpc_bench_tput_32b/rpc_bench_client_danyang-04.stdout"): + load_result('mRPC', 'ADN+mRPC', f) diff --git a/eval/policy/fault-server/config.toml b/eval/policy/fault-server/config.toml new file mode 100644 index 00000000..d6ed4a5b --- /dev/null +++ b/eval/policy/fault-server/config.toml @@ -0,0 +1,9 @@ +workdir = "~/nfs/Developing/livingshade/phoenix/experimental/mrpc" + +[env] +RUST_BACKTRACE = "1" +RUST_LOG_STYLE = "never" +CARGO_TERM_COLOR = "never" +PHOENIX_LOG = "info" +PROTOC = "/usr/bin/protoc" +PHOENIX_PREFIX = "/tmp/phoenix" diff --git a/eval/policy/fault-server/detach.toml b/eval/policy/fault-server/detach.toml new file mode 100644 index 00000000..a6b477c8 --- /dev/null +++ b/eval/policy/fault-server/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "FaultServerEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] +op = "detach" diff --git a/eval/policy/fault-server/rpc_bench_tput_32b.toml b/eval/policy/fault-server/rpc_bench_tput_32b.toml new file mode 100644 index 00000000..d1d46cd5 --- /dev/null +++ b/eval/policy/fault-server/rpc_bench_tput_32b.toml @@ -0,0 +1,15 @@ +name = "policy/fault/rpc_bench_tput_32b" +description = "Run rpc_bench benchmark" +group = "fault" +timeout_secs = 70 + +[[worker]] +host = "danyang-06" +bin = "rpc_bench_server" +args = "--port 5002 -l info --transport tcp" + +[[worker]] +host = "danyang-04" +bin = "rpc_bench_client" +args = "--transport tcp -c rdma0.danyang-06 --concurrency 128 --req-size 32 --duration 65 -i 1 --port 5002 -l error" +dependencies = [0] diff --git a/eval/policy/fault-server/start_traffic.sh b/eval/policy/fault-server/start_traffic.sh new file mode 100755 index 00000000..f0c5c3d1 --- /dev/null +++ b/eval/policy/fault-server/start_traffic.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM SIGHUP EXIT + +OD=/tmp/mrpc-eval +if [[ $# -ge 1 ]]; then + OD=$1 +fi + +WORKDIR=$(dirname $(realpath $0)) +cd $WORKDIR + +# concurrency = 128 +cargo rr --bin launcher -- --output-dir ${OD} --timeout=120 --benchmark ./rpc_bench_tput_32b.toml --configfile ./config.toml & + +sleep 30 + +LIST_OUTPUT="${OD}"/policy/list.json +cargo rr --bin list -- --dump "${LIST_OUTPUT}" # Need to specifiy PHOENIX_PREFIX +cat "${LIST_OUTPUT}" +ARG_PID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .pid') +ARG_SID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .sid') +echo $ARG_SID + +sleep 1 + +cargo run --bin addonctl -- --config ./attach.toml --pid ${ARG_PID} --sid ${ARG_SID} # Need to specifiy PHOENIX_PREFIX + +wait diff --git a/eval/policy/logging-server/README.md b/eval/policy/logging-server/README.md new file mode 100644 index 00000000..2e14d4dc --- /dev/null +++ b/eval/policy/logging-server/README.md @@ -0,0 +1,4 @@ +If you want to measure latency + +change `--concurrency 128` to `--concurrency 1` and append +`--log-latency` to the end of the args in `rpc_bench_tput_32b.toml`. diff --git a/eval/policy/logging-server/attach.toml b/eval/policy/logging-server/attach.toml new file mode 100644 index 00000000..363a235a --- /dev/null +++ b/eval/policy/logging-server/attach.toml @@ -0,0 +1,31 @@ +addon_engine = "LoggingServerEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "LoggingServerEngine", + 0, + 0, + ], + [ + "LoggingServerEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "LoggingServerEngine", + 0, + 0, + ], + [ + "LoggingServerEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" diff --git a/eval/policy/logging-server/collect.py b/eval/policy/logging-server/collect.py new file mode 100755 index 00000000..5aeb37f3 --- /dev/null +++ b/eval/policy/logging-server/collect.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +from typing import List +import glob +import sys + +OD = "/tmp/mrpc-eval" +if len(sys.argv) >= 2: + OD = sys.argv[1] + + +def get_rate(path: str) -> List[float]: + rates = [] + with open(path, 'r') as fin: + for line in fin: + words = line.strip().split(' ') + if words[-3] == 'rps,': + rate = float(words[-4]) + rates.append(rate) + return rates[1:] + + +def load_result(sol_before, sol_after, f: str): + rates = get_rate(f) + before = rates[5:25] + after = rates[-25:-5] + for r in before: + print(f'{round(r/1000,2)},{sol_before},w/o Logging') + for r in after: + print(f'{round(r/1000,2)},{sol_after},w/ Logging') + + +for f in glob.glob(OD+"/policy/logging/rpc_bench_tput_32b/rpc_bench_client_danyang-04.stdout"): + load_result('mRPC', 'Native mRPC', f) diff --git a/eval/policy/logging-server/config.toml b/eval/policy/logging-server/config.toml new file mode 100644 index 00000000..d6ed4a5b --- /dev/null +++ b/eval/policy/logging-server/config.toml @@ -0,0 +1,9 @@ +workdir = "~/nfs/Developing/livingshade/phoenix/experimental/mrpc" + +[env] +RUST_BACKTRACE = "1" +RUST_LOG_STYLE = "never" +CARGO_TERM_COLOR = "never" +PHOENIX_LOG = "info" +PROTOC = "/usr/bin/protoc" +PHOENIX_PREFIX = "/tmp/phoenix" diff --git a/eval/policy/logging-server/detach.toml b/eval/policy/logging-server/detach.toml new file mode 100644 index 00000000..a236b2c2 --- /dev/null +++ b/eval/policy/logging-server/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "LoggingServerEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] +op = "detach" diff --git a/eval/policy/logging-server/rpc_bench_tput_32b.toml b/eval/policy/logging-server/rpc_bench_tput_32b.toml new file mode 100644 index 00000000..b8aae34e --- /dev/null +++ b/eval/policy/logging-server/rpc_bench_tput_32b.toml @@ -0,0 +1,15 @@ +name = "policy/logging/rpc_bench_tput_32b" +description = "Run rpc_bench benchmark" +group = "logging" +timeout_secs = 70 + +[[worker]] +host = "danyang-06" +bin = "rpc_bench_server" +args = "--port 5002 -l info --transport tcp" + +[[worker]] +host = "danyang-04" +bin = "rpc_bench_client" +args = "--transport tcp -c rdma0.danyang-06 --concurrency 128 --req-size 32 --duration 65 -i 1 --port 5002 -l info" +dependencies = [0] diff --git a/eval/policy/logging-server/run_policy.py b/eval/policy/logging-server/run_policy.py new file mode 100755 index 00000000..02baaf74 --- /dev/null +++ b/eval/policy/logging-server/run_policy.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +import json +import subprocess +import pathlib +import os +from os.path import dirname +import time +import toml +import sys + +OD = "/tmp/mrpc-eval" +if len(sys.argv) >= 2: + OD = sys.argv[1] + +SCRIPTDIR = pathlib.Path(__file__).parent.resolve() +CONFIG_PATH = os.path.join(SCRIPTDIR, "config.toml") + +config = toml.load(CONFIG_PATH) +workdir = config["workdir"] +workdir = dirname(dirname(os.path.expanduser(workdir))) +env = {**os.environ, **config['env']} + +os.chdir(workdir) +os.makedirs(f"{OD}/policy/null", exist_ok=True) + +cmd = f'''cargo run --release -p benchmark --bin launcher -- -o {OD} --timeout=120 +--benchmark {os.path.join(SCRIPTDIR, 'rpc_bench_tput_32b.toml')} +--configfile { os.path.join(SCRIPTDIR, 'config.toml')}''' +workload = subprocess.Popen(cmd.split()) +time.sleep(30) + +list_cmd = f"cargo run --release --bin list -- --dump {OD}/policy/list.json" +subprocess.run(list_cmd.split(), env=env) + +with open(f"{OD}/policy/list.json", "r") as fin: + content = fin.read() + print(content) + data = json.loads(content) +mrpc_pid = None +mrpc_sid = None +for subscription in data: + pid = subscription["pid"] + sid = subscription["sid"] + engines = [x[1] for x in subscription["engines"]] + if "MrpcEngine" in engines: + mrpc_pid = pid + mrpc_sid = sid + +print("Start to attach policy") +attach_config = os.path.join(SCRIPTDIR, "attach.toml") +attach_cmd = f"cargo run --release --bin addonctl -- --config {attach_config} --pid {mrpc_pid} --sid {mrpc_sid}" +subprocess.run(attach_cmd.split(), env=env) + +subprocess.run(list_cmd.split(), env=env) +with open(f"{OD}/policy/list.json", "r") as fin: + print(fin.read()) + +workload.wait() diff --git a/eval/policy/metrics-server/attach.toml b/eval/policy/metrics-server/attach.toml new file mode 100644 index 00000000..7c9d0caa --- /dev/null +++ b/eval/policy/metrics-server/attach.toml @@ -0,0 +1,33 @@ +addon_engine = "MetricsServerEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "MetricsServerEngine", + 0, + 0, + ], + [ + "MetricsServerEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "MetricsServerEngine", + 0, + 0, + ], + [ + "MetricsServerEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +''' diff --git a/eval/policy/metrics-server/collect.py b/eval/policy/metrics-server/collect.py new file mode 100755 index 00000000..009eec0d --- /dev/null +++ b/eval/policy/metrics-server/collect.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from typing import List +import glob +import sys + +OD = "/tmp/mrpc-eval" +if len(sys.argv) >= 2: + OD = sys.argv[1] + + +def convert_msg_size(s: str) -> int: + if s.endswith('gb'): + return int(s[:-2]) * 1024 * 1024 * 1024 + if s.endswith('mb'): + return int(s[:-2]) * 1024 * 1024 + if s.endswith('kb'): + return int(s[:-2]) * 1024 + if s.endswith('b'): + return int(s[:-1]) + + raise ValueError(f"unknown input: {s}") + + +def get_rate(path: str) -> List[float]: + rates = [] + with open(path, 'r') as fin: + for line in fin: + words = line.strip().split(' ') + if words[-3] == 'rps,': + rate = float(words[-4]) + rates.append(rate) + return rates[1:] + + +def load_result(sol_before, sol_after, f: str): + # print(f) + rates = get_rate(f) + before = rates[5:25] + after = rates[-25:-5] + for r in before: + print(f'{round(r/1000,2)},{sol_before},w/o Fault') + for r in after: + print(f'{round(r/1000,2)},{sol_after},w/ Fault') + + +for f in glob.glob(OD+"/policy/fault/rpc_bench_tput_32b/rpc_bench_client_danyang-04.stdout"): + load_result('mRPC', 'ADN+mRPC', f) diff --git a/eval/policy/metrics-server/config.toml b/eval/policy/metrics-server/config.toml new file mode 100644 index 00000000..d6ed4a5b --- /dev/null +++ b/eval/policy/metrics-server/config.toml @@ -0,0 +1,9 @@ +workdir = "~/nfs/Developing/livingshade/phoenix/experimental/mrpc" + +[env] +RUST_BACKTRACE = "1" +RUST_LOG_STYLE = "never" +CARGO_TERM_COLOR = "never" +PHOENIX_LOG = "info" +PROTOC = "/usr/bin/protoc" +PHOENIX_PREFIX = "/tmp/phoenix" diff --git a/eval/policy/metrics-server/detach.toml b/eval/policy/metrics-server/detach.toml new file mode 100644 index 00000000..88214f94 --- /dev/null +++ b/eval/policy/metrics-server/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "MetricsServerEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] +op = "detach" diff --git a/eval/policy/metrics-server/rpc_bench_tput_32b.toml b/eval/policy/metrics-server/rpc_bench_tput_32b.toml new file mode 100644 index 00000000..d1d46cd5 --- /dev/null +++ b/eval/policy/metrics-server/rpc_bench_tput_32b.toml @@ -0,0 +1,15 @@ +name = "policy/fault/rpc_bench_tput_32b" +description = "Run rpc_bench benchmark" +group = "fault" +timeout_secs = 70 + +[[worker]] +host = "danyang-06" +bin = "rpc_bench_server" +args = "--port 5002 -l info --transport tcp" + +[[worker]] +host = "danyang-04" +bin = "rpc_bench_client" +args = "--transport tcp -c rdma0.danyang-06 --concurrency 128 --req-size 32 --duration 65 -i 1 --port 5002 -l error" +dependencies = [0] diff --git a/eval/policy/metrics-server/start_traffic.sh b/eval/policy/metrics-server/start_traffic.sh new file mode 100755 index 00000000..f0c5c3d1 --- /dev/null +++ b/eval/policy/metrics-server/start_traffic.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM SIGHUP EXIT + +OD=/tmp/mrpc-eval +if [[ $# -ge 1 ]]; then + OD=$1 +fi + +WORKDIR=$(dirname $(realpath $0)) +cd $WORKDIR + +# concurrency = 128 +cargo rr --bin launcher -- --output-dir ${OD} --timeout=120 --benchmark ./rpc_bench_tput_32b.toml --configfile ./config.toml & + +sleep 30 + +LIST_OUTPUT="${OD}"/policy/list.json +cargo rr --bin list -- --dump "${LIST_OUTPUT}" # Need to specifiy PHOENIX_PREFIX +cat "${LIST_OUTPUT}" +ARG_PID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .pid') +ARG_SID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .sid') +echo $ARG_SID + +sleep 1 + +cargo run --bin addonctl -- --config ./attach.toml --pid ${ARG_PID} --sid ${ARG_SID} # Need to specifiy PHOENIX_PREFIX + +wait diff --git a/eval/policy/mutation-server/attach.toml b/eval/policy/mutation-server/attach.toml new file mode 100644 index 00000000..c3ded6ef --- /dev/null +++ b/eval/policy/mutation-server/attach.toml @@ -0,0 +1,31 @@ +addon_engine = "MutationServerEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "MutationServerEngine", + 0, + 0, + ], + [ + "MutationServerEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "MutationServerEngine", + 0, + 0, + ], + [ + "MutationServerEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" diff --git a/eval/policy/mutation-server/detach.toml b/eval/policy/mutation-server/detach.toml new file mode 100644 index 00000000..c92148aa --- /dev/null +++ b/eval/policy/mutation-server/detach.toml @@ -0,0 +1,6 @@ +addon_engine = "MutationServerEngine" +tx_channels_replacements = [ + ["MrpcEngine", "RpcAdapterEngine", 0, 0], +] +rx_channels_replacements = [] +op = "detach" diff --git a/eval/policy/ratelimit-drop-server/attach.toml b/eval/policy/ratelimit-drop-server/attach.toml new file mode 100644 index 00000000..628dd94b --- /dev/null +++ b/eval/policy/ratelimit-drop-server/attach.toml @@ -0,0 +1,35 @@ +addon_engine = "RateLimitDropEngine" +tx_channels_replacements = [ + [ + "MrpcEngine", + "RateLimitDropServerEngine", + 0, + 0, + ], + [ + "RateLimitDropServerEngine", + "TcpRpcAdapterEngine", + 0, + 0, + ], +] +rx_channels_replacements = [ + [ + "TcpRpcAdapterEngine", + "RateLimitDropServerEngine", + 0, + 0, + ], + [ + "RateLimitDropServerEngine", + "MrpcEngine", + 0, + 0, + ], +] +group = ["MrpcEngine", "TcpRpcAdapterEngine"] +op = "attach" +config_string = ''' +requests_per_sec = 1 +bucket_size = 2 +''' diff --git a/eval/policy/ratelimit-drop-server/detach.toml b/eval/policy/ratelimit-drop-server/detach.toml new file mode 100644 index 00000000..9c45c4f0 --- /dev/null +++ b/eval/policy/ratelimit-drop-server/detach.toml @@ -0,0 +1,4 @@ +addon_engine = "RateLimitDropServerEngine" +tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] +op = "detach" From eded4e7bee626eb5fb1efac10a052a27512abebc Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 3 Dec 2023 03:57:12 +0000 Subject: [PATCH 17/21] update --- eval/policy/ratelimit-drop-server/attach.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eval/policy/ratelimit-drop-server/attach.toml b/eval/policy/ratelimit-drop-server/attach.toml index 628dd94b..49d9c82c 100644 --- a/eval/policy/ratelimit-drop-server/attach.toml +++ b/eval/policy/ratelimit-drop-server/attach.toml @@ -1,4 +1,4 @@ -addon_engine = "RateLimitDropEngine" +addon_engine = "RateLimitDropServerEngine" tx_channels_replacements = [ [ "MrpcEngine", From 5a36e8e3d83325a5fea6b61b1261f60b092fe846 Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 3 Dec 2023 04:45:09 +0000 Subject: [PATCH 18/21] fix scripts --- eval/policy/hello-acl-receiver/detach.toml | 2 +- experimental/mrpc/Cargo.lock | 34 ++ experimental/mrpc/Cargo.toml | 453 ++++++++++++++------- 3 files changed, 334 insertions(+), 155 deletions(-) diff --git a/eval/policy/hello-acl-receiver/detach.toml b/eval/policy/hello-acl-receiver/detach.toml index d77a7d9a..23f93a0e 100644 --- a/eval/policy/hello-acl-receiver/detach.toml +++ b/eval/policy/hello-acl-receiver/detach.toml @@ -1,4 +1,4 @@ addon_engine = "HelloAclReceiverEngine" tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] -rx_channels_replacements = [] +rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] op = "detach" diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index f862caf6..5db7a894 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1694,6 +1694,16 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-genaclserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + [[package]] name = "phoenix-api-policy-hello-acl" version = "0.1.0" @@ -1975,6 +1985,30 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-genaclserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genaclserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-hello-acl" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 57904404..4b5a4d45 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -3,164 +3,167 @@ name = "mrpc" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [features] -timing = ["dep:minstant"] - -[dependencies] -phoenix-api-mrpc.workspace = true - -phoenix-api = { workspace = true, features = ["mrpc"] } -ipc = { workspace = true, features = ["customer"] } -shm = { workspace = true, features = ["mrpc"] } -mmap.workspace = true -phoenix-syscalls.workspace = true -shmalloc.workspace = true - -minstant = { workspace = true, optional = true } -thiserror.workspace = true -uuid.workspace = true -libc.workspace = true -fnv.workspace = true -memfd.workspace = true -lazy_static.workspace = true -tracing.workspace = true -dashmap.workspace = true -async-executor.workspace = true -arrayvec.workspace = true -async-trait.workspace = true -log.workspace = true -futures.workspace = true -serde_json.workspace = true -libnuma.workspace = true -slab.workspace = true -spin.workspace = true +timing = [ + "dep:minstant", +] + +[dependencies.phoenix-api-mrpc] +workspace = true + +[dependencies.phoenix-api] +workspace = true +features = [ + "mrpc", +] + +[dependencies.ipc] +workspace = true +features = [ + "customer", +] + +[dependencies.shm] +workspace = true +features = [ + "mrpc", +] + +[dependencies.mmap] +workspace = true + +[dependencies.phoenix-syscalls] +workspace = true + +[dependencies.shmalloc] +workspace = true + +[dependencies.minstant] +workspace = true +optional = true + +[dependencies.thiserror] +workspace = true + +[dependencies.uuid] +workspace = true + +[dependencies.libc] +workspace = true + +[dependencies.fnv] +workspace = true + +[dependencies.memfd] +workspace = true + +[dependencies.lazy_static] +workspace = true + +[dependencies.tracing] +workspace = true + +[dependencies.dashmap] +workspace = true + +[dependencies.async-executor] +workspace = true + +[dependencies.arrayvec] +workspace = true + +[dependencies.async-trait] +workspace = true + +[dependencies.log] +workspace = true + +[dependencies.futures] +workspace = true + +[dependencies.serde_json] +workspace = true + +[dependencies.libnuma] +workspace = true + +[dependencies.slab] +workspace = true + +[dependencies.spin] +workspace = true [workspace] members = [ - # mrpc user-land libraries - "mrpc-build", - "mrpc-derive", - "mrpc-marshal", - # extension to phoenix-api - "phoenix-api/mrpc", - "phoenix-api/mrpclb", - "phoenix-api/rpc_adapter", - "phoenix-api/tcp_rpc_adapter", - "phoenix-api/load_balancer", - "phoenix-api/policy/null", - "phoenix-api/policy/ratelimit", - "phoenix-api/policy/ratelimit-drop", - "phoenix-api/policy/qos", - "phoenix-api/policy/hotel-acl", - "phoenix-api/policy/logging", - "phoenix-api/policy/hello-acl-receiver", - "phoenix-api/policy/hello-acl-sender", - "phoenix-api/policy/hello-acl", - "phoenix-api/policy/nofile-logging", - "phoenix-api/policy/fault", - "phoenix-api/policy/fault2", - "phoenix-api/policy/delay", - "phoenix-api/policy/admission-control", - "phoenix-api/policy/metrics", - "phoenix-api/policy/mutation", - "phoenix-api/policy/fault-server", - "phoenix-api/policy/logging-server", - "phoenix-api/policy/metrics-server", - "phoenix-api/policy/mutation-server", - "phoenix-api/policy/ratelimit-drop-server", - # the phoenix plugins - "plugin/mrpc", - "plugin/mrpclb", - "plugin/rpc_adapter", - "plugin/tcp_rpc_adapter", - "plugin/load_balancer", - # TODO(cjr): Add them back - "plugin/policy/null", - "plugin/policy/ratelimit", - "plugin/policy/ratelimit-drop", - "plugin/policy/qos", - "plugin/policy/logging", - "plugin/policy/hotel-acl", - "plugin/policy/hello-acl-receiver", - "plugin/policy/hello-acl-sender", - "plugin/policy/hello-acl", - "plugin/policy/nofile-logging", - "plugin/policy/fault", - "plugin/policy/fault2", - "plugin/policy/delay", - "plugin/policy/admission-control", - "plugin/policy/metrics", - "plugin/policy/mutation", - "plugin/policy/fault-server", - "plugin/policy/logging-server", - "plugin/policy/metrics-server", - "plugin/policy/mutation-server", - "plugin/policy/ratelimit-drop-server", - # examples - "examples/rpc_echo", - "examples/rpc_bench", - "examples/rpc_bench_plus", - "examples/masstree_analytics", - "examples/hotel_reservation", - "examples/load_balancer", - # "examples/hotel_microservices", + "mrpc-build", + "mrpc-derive", + "mrpc-marshal", + "phoenix-api/mrpc", + "phoenix-api/mrpclb", + "phoenix-api/rpc_adapter", + "phoenix-api/tcp_rpc_adapter", + "phoenix-api/load_balancer", + "phoenix-api/policy/null", + "phoenix-api/policy/ratelimit", + "phoenix-api/policy/ratelimit-drop", + "phoenix-api/policy/qos", + "phoenix-api/policy/hotel-acl", + "phoenix-api/policy/logging", + "phoenix-api/policy/hello-acl-receiver", + "phoenix-api/policy/hello-acl-sender", + "phoenix-api/policy/hello-acl", + "phoenix-api/policy/nofile-logging", + "phoenix-api/policy/fault", + "phoenix-api/policy/fault2", + "phoenix-api/policy/delay", + "phoenix-api/policy/admission-control", + "phoenix-api/policy/metrics", + "phoenix-api/policy/mutation", + "phoenix-api/policy/fault-server", + "phoenix-api/policy/logging-server", + "phoenix-api/policy/metrics-server", + "phoenix-api/policy/mutation-server", + "phoenix-api/policy/ratelimit-drop-server", + "plugin/mrpc", + "plugin/mrpclb", + "plugin/rpc_adapter", + "plugin/tcp_rpc_adapter", + "plugin/load_balancer", + "plugin/policy/null", + "plugin/policy/ratelimit", + "plugin/policy/ratelimit-drop", + "plugin/policy/qos", + "plugin/policy/logging", + "plugin/policy/hotel-acl", + "plugin/policy/hello-acl-receiver", + "plugin/policy/hello-acl-sender", + "plugin/policy/hello-acl", + "plugin/policy/nofile-logging", + "plugin/policy/fault", + "plugin/policy/fault2", + "plugin/policy/delay", + "plugin/policy/admission-control", + "plugin/policy/metrics", + "plugin/policy/mutation", + "plugin/policy/fault-server", + "plugin/policy/logging-server", + "plugin/policy/metrics-server", + "plugin/policy/mutation-server", + "plugin/policy/ratelimit-drop-server", + "examples/rpc_echo", + "examples/rpc_bench", + "examples/rpc_bench_plus", + "examples/masstree_analytics", + "examples/hotel_reservation", + "examples/load_balancer", + "generated/api/genaclserver", + "generated/plugin/genaclserver", +] +exclude = [ + "3rdparty/prost", ] -exclude = ["3rdparty/prost"] - [workspace.dependencies] -mrpc = { path = "." } -phoenix-api-mrpc = { path = "phoenix-api/mrpc" } -phoenix-api-mrpclb = { path = "phoenix-api/mrpclb" } -phoenix-api-tcp-rpc-adapter = { path = "phoenix-api/tcp_rpc_adapter" } -phoenix-api-rpc-adapter = { path = "phoenix-api/rpc_adapter" } -phoenix-api-load-balancer = { path = "phoenix-api/load_balancer" } -phoenix-api-policy-null = { path = "phoenix-api/policy/null" } -phoenix-api-policy-ratelimit = { path = "phoenix-api/policy/ratelimit" } -phoenix-api-policy-ratelimit-drop = { path = "phoenix-api/policy/ratelimit-drop" } -phoenix-api-policy-qos = { path = "phoenix-api/policy/qos" } -phoenix-api-policy-hotel-acl = { path = "phoenix-api/policy/hotel-acl" } -phoenix-api-policy-logging = { path = "phoenix-api/policy/logging" } -phoenix-api-policy-hello-acl-receiver = { path = "phoenix-api/policy/hello-acl-receiver" } -phoenix-api-policy-hello-acl-sender = { path = "phoenix-api/policy/hello-acl-sender" } -phoenix-api-policy-hello-acl = { path = "phoenix-api/policy/hello-acl" } -phoenix-api-policy-nofile-logging = { path = "phoenix-api/policy/nofile-logging" } -phoenix-api-policy-fault = { path = "phoenix-api/policy/fault" } -phoenix-api-policy-fault2 = { path = "phoenix-api/policy/fault2" } -phoenix-api-policy-delay = { path = "phoenix-api/policy/delay" } -phoenix-api-policy-admission-control = { path = "phoenix-api/policy/admission-control" } -phoenix-api-policy-metrics = { path = "phoenix-api/policy/metrics" } -phoenix-api-policy-mutation = { path = "phoenix-api/policy/mutation" } -phoenix-api-policy-fault-server = { path = "phoenix-api/policy/fault-server" } -phoenix-api-policy-logging-server = { path = "phoenix-api/policy/logging-server" } -phoenix-api-policy-metrics-server = { path = "phoenix-api/policy/metrics-server" } -phoenix-api-policy-mutation-server = { path = "phoenix-api/policy/mutation-server" } -phoenix-api-policy-ratelimit-drop-server = { path = "phoenix-api/policy/ratelimit-drop-server" } - - -mrpc-build = { path = "mrpc-build" } -mrpc-derive = { path = "mrpc-derive" } -mrpc-marshal = { path = "mrpc-marshal" } -prost = { path = "3rdparty/prost" } -prost-build = { path = "3rdparty/prost/prost-build" } -phoenix-mrpc = { path = "plugin/mrpc" } -phoenix-mrpclb = { path = "plugin/mrpclb" } - -phoenix-syscalls = { path = "../../src/phoenix-syscalls" } -phoenix-api = { path = "../../src/phoenix-api" } -ipc = { path = "../../src/ipc" } -mmap = { path = "../../src/mmap" } -rdma = { path = "../../src/rdma" } -shm = { path = "../../src/shm" } -shmalloc = { path = "../../src/shm/shmalloc" } -phoenix_common = { path = "../../src/phoenix_common" } -transport-rdma = { path = "../../src/plugin/transport-rdma", package = "phoenix-transport-rdma" } -transport-tcp = { path = "../../src/plugin/transport-tcp", package = "phoenix-transport-tcp" } -phoenix-salloc = { path = "../../src/plugin/salloc", package = "phoenix-salloc" } -utils = { path = "../../src/utils" } - thiserror = "1.0.31" uuid = "0.8.2" libc = "0.2.103" @@ -181,7 +184,7 @@ futures = "0.3.23" libnuma = "0.0.4" spin = "0.9.3" static_assertions = "1.1.0" -tokio = "1.18.2" # only sync is enabled +tokio = "1.18.2" anyhow = "1.0.58" itertools = "0.10.3" crc32fast = "1.3.2" @@ -192,13 +195,11 @@ proc-macro2 = "1.0.40" md5 = "0.7.0" prettyplease = "0.1.15" toml = "0.5.8" - libloading = "0.7.3" bitvec = "1.0.1" bincode = "1.3.3" socket2 = "0.4.7" slab = "0.4.7" - smol = "1.2.5" structopt = "0.3.23" tracing-subscriber = "0.3" @@ -214,5 +215,149 @@ arc-swap = "1.5.0" crossbeam-utils = "0.8.12" rand = "0.8" +[workspace.dependencies.mrpc] +path = "." + +[workspace.dependencies.phoenix-api-mrpc] +path = "phoenix-api/mrpc" + +[workspace.dependencies.phoenix-api-mrpclb] +path = "phoenix-api/mrpclb" + +[workspace.dependencies.phoenix-api-tcp-rpc-adapter] +path = "phoenix-api/tcp_rpc_adapter" + +[workspace.dependencies.phoenix-api-rpc-adapter] +path = "phoenix-api/rpc_adapter" + +[workspace.dependencies.phoenix-api-load-balancer] +path = "phoenix-api/load_balancer" + +[workspace.dependencies.phoenix-api-policy-null] +path = "phoenix-api/policy/null" + +[workspace.dependencies.phoenix-api-policy-ratelimit] +path = "phoenix-api/policy/ratelimit" + +[workspace.dependencies.phoenix-api-policy-ratelimit-drop] +path = "phoenix-api/policy/ratelimit-drop" + +[workspace.dependencies.phoenix-api-policy-qos] +path = "phoenix-api/policy/qos" + +[workspace.dependencies.phoenix-api-policy-hotel-acl] +path = "phoenix-api/policy/hotel-acl" + +[workspace.dependencies.phoenix-api-policy-logging] +path = "phoenix-api/policy/logging" + +[workspace.dependencies.phoenix-api-policy-hello-acl-receiver] +path = "phoenix-api/policy/hello-acl-receiver" + +[workspace.dependencies.phoenix-api-policy-hello-acl-sender] +path = "phoenix-api/policy/hello-acl-sender" + +[workspace.dependencies.phoenix-api-policy-hello-acl] +path = "phoenix-api/policy/hello-acl" + +[workspace.dependencies.phoenix-api-policy-nofile-logging] +path = "phoenix-api/policy/nofile-logging" + +[workspace.dependencies.phoenix-api-policy-fault] +path = "phoenix-api/policy/fault" + +[workspace.dependencies.phoenix-api-policy-fault2] +path = "phoenix-api/policy/fault2" + +[workspace.dependencies.phoenix-api-policy-delay] +path = "phoenix-api/policy/delay" + +[workspace.dependencies.phoenix-api-policy-admission-control] +path = "phoenix-api/policy/admission-control" + +[workspace.dependencies.phoenix-api-policy-metrics] +path = "phoenix-api/policy/metrics" + +[workspace.dependencies.phoenix-api-policy-mutation] +path = "phoenix-api/policy/mutation" + +[workspace.dependencies.phoenix-api-policy-fault-server] +path = "phoenix-api/policy/fault-server" + +[workspace.dependencies.phoenix-api-policy-logging-server] +path = "phoenix-api/policy/logging-server" + +[workspace.dependencies.phoenix-api-policy-metrics-server] +path = "phoenix-api/policy/metrics-server" + +[workspace.dependencies.phoenix-api-policy-mutation-server] +path = "phoenix-api/policy/mutation-server" + +[workspace.dependencies.phoenix-api-policy-ratelimit-drop-server] +path = "phoenix-api/policy/ratelimit-drop-server" + +[workspace.dependencies.mrpc-build] +path = "mrpc-build" + +[workspace.dependencies.mrpc-derive] +path = "mrpc-derive" + +[workspace.dependencies.mrpc-marshal] +path = "mrpc-marshal" + +[workspace.dependencies.prost] +path = "3rdparty/prost" + +[workspace.dependencies.prost-build] +path = "3rdparty/prost/prost-build" + +[workspace.dependencies.phoenix-mrpc] +path = "plugin/mrpc" + +[workspace.dependencies.phoenix-mrpclb] +path = "plugin/mrpclb" + +[workspace.dependencies.phoenix-syscalls] +path = "../../src/phoenix-syscalls" + +[workspace.dependencies.phoenix-api] +path = "../../src/phoenix-api" + +[workspace.dependencies.ipc] +path = "../../src/ipc" + +[workspace.dependencies.mmap] +path = "../../src/mmap" + +[workspace.dependencies.rdma] +path = "../../src/rdma" + +[workspace.dependencies.shm] +path = "../../src/shm" + +[workspace.dependencies.shmalloc] +path = "../../src/shm/shmalloc" + +[workspace.dependencies.phoenix_common] +path = "../../src/phoenix_common" + +[workspace.dependencies.transport-rdma] +path = "../../src/plugin/transport-rdma" +package = "phoenix-transport-rdma" + +[workspace.dependencies.transport-tcp] +path = "../../src/plugin/transport-tcp" +package = "phoenix-transport-tcp" + +[workspace.dependencies.phoenix-salloc] +path = "../../src/plugin/salloc" +package = "phoenix-salloc" + +[workspace.dependencies.utils] +path = "../../src/utils" + +[workspace.dependencies.phoenix-api-policy-genaclserver] +path = "generated/api/genaclserver" + [profile.release] debug = true From 607eacf383c2a76a7a9c630d9fbfe17939e82d43 Mon Sep 17 00:00:00 2001 From: banruo Date: Sun, 3 Dec 2023 06:38:03 +0000 Subject: [PATCH 19/21] fix --- Makefile.toml | 2 +- experimental/mrpc/Cargo.lock | 34 ---------------------------------- experimental/mrpc/Cargo.toml | 24 +++++------------------- 3 files changed, 6 insertions(+), 54 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index b7a9b44f..e3a1fc8f 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -22,7 +22,7 @@ dependencies = [ "build-phoenixos", "build-plugins", "deploy-plugins", - # "run-phoenixos", + "run-phoenixos", ] [tasks.phoenix_common] diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index 5db7a894..f862caf6 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1694,16 +1694,6 @@ dependencies = [ "serde", ] -[[package]] -name = "phoenix-api-policy-genaclserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - [[package]] name = "phoenix-api-policy-hello-acl" version = "0.1.0" @@ -1985,30 +1975,6 @@ dependencies = [ "toml", ] -[[package]] -name = "phoenix-genaclserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genaclserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - [[package]] name = "phoenix-hello-acl" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 4b5a4d45..2a6b6b6c 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -4,30 +4,22 @@ version = "0.1.0" edition = "2021" [features] -timing = [ - "dep:minstant", -] +timing = ["dep:minstant"] [dependencies.phoenix-api-mrpc] workspace = true [dependencies.phoenix-api] workspace = true -features = [ - "mrpc", -] +features = ["mrpc"] [dependencies.ipc] workspace = true -features = [ - "customer", -] +features = ["customer"] [dependencies.shm] workspace = true -features = [ - "mrpc", -] +features = ["mrpc"] [dependencies.mmap] workspace = true @@ -156,12 +148,8 @@ members = [ "examples/masstree_analytics", "examples/hotel_reservation", "examples/load_balancer", - "generated/api/genaclserver", - "generated/plugin/genaclserver", -] -exclude = [ - "3rdparty/prost", ] +exclude = ["3rdparty/prost"] [workspace.dependencies] thiserror = "1.0.31" @@ -356,8 +344,6 @@ package = "phoenix-salloc" [workspace.dependencies.utils] path = "../../src/utils" -[workspace.dependencies.phoenix-api-policy-genaclserver] -path = "generated/api/genaclserver" [profile.release] debug = true From 2dfce09c48959feed9d314d1ac6c819f3893b97e Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 4 Dec 2023 07:19:25 +0000 Subject: [PATCH 20/21] update ratelimit --- experimental/mrpc/Cargo.lock | 238 ++++++++++++++++++ experimental/mrpc/Cargo.toml | 92 ++++++- .../policy/ratelimit-drop/src/engine.rs | 63 ++--- 3 files changed, 347 insertions(+), 46 deletions(-) diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index f862caf6..c96fbc97 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1694,6 +1694,76 @@ dependencies = [ "serde", ] +[[package]] +name = "phoenix-api-policy-genaclserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genfaultserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genloggingserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genmetricsserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genmutationserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genratelimitclient" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "phoenix-api-policy-genratelimitserver" +version = "0.1.0" +dependencies = [ + "itertools", + "phoenix-api", + "rand 0.8.5", + "serde", +] + [[package]] name = "phoenix-api-policy-hello-acl" version = "0.1.0" @@ -1975,6 +2045,174 @@ dependencies = [ "toml", ] +[[package]] +name = "phoenix-genaclserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genaclserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genfaultserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genfaultserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genloggingserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genloggingserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genmetricsserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genmetricsserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genmutationserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genmutationserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genratelimitclient" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genratelimitclient", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + +[[package]] +name = "phoenix-genratelimitserver" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "futures", + "itertools", + "minstant", + "mrpc-derive", + "mrpc-marshal", + "nix", + "phoenix-api", + "phoenix-api-policy-genratelimitserver", + "phoenix_common", + "rand 0.8.5", + "serde", + "serde_json", + "shm", + "thiserror", + "toml", +] + [[package]] name = "phoenix-hello-acl" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index 2a6b6b6c..ede410cd 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -4,22 +4,30 @@ version = "0.1.0" edition = "2021" [features] -timing = ["dep:minstant"] +timing = [ + "dep:minstant", +] [dependencies.phoenix-api-mrpc] workspace = true [dependencies.phoenix-api] workspace = true -features = ["mrpc"] +features = [ + "mrpc", +] [dependencies.ipc] workspace = true -features = ["customer"] +features = [ + "customer", +] [dependencies.shm] workspace = true -features = ["mrpc"] +features = [ + "mrpc", +] [dependencies.mmap] workspace = true @@ -148,8 +156,62 @@ members = [ "examples/masstree_analytics", "examples/hotel_reservation", "examples/load_balancer", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitclient", + "generated/plugin/genratelimitclient", + "generated/api/genratelimitserver", + "generated/plugin/genratelimitserver", + "generated/api/genloggingserver", + "generated/plugin/genloggingserver", + "generated/api/genloggingserver", + "generated/plugin/genloggingserver", + "generated/api/genmutationserver", + "generated/plugin/genmutationserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genmetricsserver", + "generated/plugin/genmetricsserver", + "generated/api/genfaultserver", + "generated/plugin/genfaultserver", + "generated/api/genfaultserver", + "generated/plugin/genfaultserver", + "generated/api/genfaultserver", + "generated/plugin/genfaultserver", + "generated/api/genfaultserver", + "generated/plugin/genfaultserver", + "generated/api/genfaultserver", + "generated/plugin/genfaultserver", + "generated/api/genaclserver", + "generated/plugin/genaclserver", +] +exclude = [ + "3rdparty/prost", ] -exclude = ["3rdparty/prost"] [workspace.dependencies] thiserror = "1.0.31" @@ -344,6 +406,26 @@ package = "phoenix-salloc" [workspace.dependencies.utils] path = "../../src/utils" +[workspace.dependencies.phoenix-api-policy-genratelimitclient] +path = "generated/api/genratelimitclient" + +[workspace.dependencies.phoenix-api-policy-genratelimitserver] +path = "generated/api/genratelimitserver" + +[workspace.dependencies.phoenix-api-policy-genloggingserver] +path = "generated/api/genloggingserver" + +[workspace.dependencies.phoenix-api-policy-genmutationserver] +path = "generated/api/genmutationserver" + +[workspace.dependencies.phoenix-api-policy-genmetricsserver] +path = "generated/api/genmetricsserver" + +[workspace.dependencies.phoenix-api-policy-genfaultserver] +path = "generated/api/genfaultserver" + +[workspace.dependencies.phoenix-api-policy-genaclserver] +path = "generated/api/genaclserver" [profile.release] debug = true diff --git a/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs b/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs index cd807fe7..3728d586 100644 --- a/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs +++ b/experimental/mrpc/plugin/policy/ratelimit-drop/src/engine.rs @@ -183,53 +183,34 @@ impl RateLimitDropEngine { match self.tx_inputs()[0].try_recv() { Ok(msg) => { match msg { - EngineTxMessage::RpcMessage(msg) => { - let meta_ref = unsafe { &*msg.meta_buf_ptr.as_meta_ptr() }; - let mut input = Vec::new(); - input.push(msg); + EngineTxMessage::RpcMessage(req) => { self.num_tokens = self.num_tokens + (current_timestamp() - self.last_ts).as_secs_f64() * self.config.requests_per_sec as f64; self.last_ts = current_timestamp(); - log::debug!("num_tokens: {}", self.num_tokens); - let limit = std::cmp::min(input.len() as i64, self.num_tokens as i64); - self.num_tokens = self.num_tokens - limit as f64; - - let output = input.iter().enumerate().map(|(index, req)| { - let rpc_message = materialize_nocopy(&req); - let conn_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.conn_id; - let call_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.call_id; - let rpc_id = RpcId::new(conn_id, call_id); - if index < limit as usize { - let raw_ptr: *const hello::HelloRequest = rpc_message; - let new_msg = RpcMessageTx { - meta_buf_ptr: req.meta_buf_ptr.clone(), - addr_backend: req.addr_backend, - }; - RpcMessageGeneral::TxMessage(EngineTxMessage::RpcMessage(new_msg)) - } else { - let error = EngineRxMessage::Ack( - rpc_id, - TransportStatus::Error(unsafe { - NonZeroU32::new_unchecked(403) - }), - ); - RpcMessageGeneral::RxMessage(error) - } - }); - for msg in output { - match msg { - RpcMessageGeneral::TxMessage(msg) => { - self.tx_outputs()[0].send(msg)?; - } - RpcMessageGeneral::RxMessage(msg) => { - self.rx_outputs()[0].send(msg)?; - } - _ => {} - } + let rpc_message = materialize_nocopy(&req); + let conn_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.conn_id; + let call_id = unsafe { &*req.meta_buf_ptr.as_meta_ptr() }.call_id; + let rpc_id = RpcId::new(conn_id, call_id); + if self.num_tokens > 1.0 { + let raw_ptr: *const hello::HelloRequest = rpc_message; + let new_msg = RpcMessageTx { + meta_buf_ptr: req.meta_buf_ptr.clone(), + addr_backend: req.addr_backend, + }; + self.tx_outputs()[0].send(EngineTxMessage::RpcMessage(new_msg))?; + } else { + self.num_tokens = self.num_tokens - 1.0; + let error = EngineRxMessage::Ack( + rpc_id, + TransportStatus::Error(unsafe { NonZeroU32::new_unchecked(403) }), + ); + self.rx_outputs()[0].send(error)?; } } - m => self.tx_outputs()[0].send(m)?, + m => { + self.tx_outputs()[0].send(m)?; + } } return Ok(Progress(1)); } From d0925b6ae60bfc4d7967df39ca3be95ac82148f8 Mon Sep 17 00:00:00 2001 From: banruo Date: Mon, 4 Dec 2023 07:42:49 +0000 Subject: [PATCH 21/21] update cargo --- experimental/mrpc/Cargo.lock | 238 ----------------------------------- experimental/mrpc/Cargo.toml | 93 +------------- 2 files changed, 5 insertions(+), 326 deletions(-) diff --git a/experimental/mrpc/Cargo.lock b/experimental/mrpc/Cargo.lock index c96fbc97..f862caf6 100644 --- a/experimental/mrpc/Cargo.lock +++ b/experimental/mrpc/Cargo.lock @@ -1694,76 +1694,6 @@ dependencies = [ "serde", ] -[[package]] -name = "phoenix-api-policy-genaclserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genfaultserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genloggingserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genmetricsserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genmutationserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genratelimitclient" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "phoenix-api-policy-genratelimitserver" -version = "0.1.0" -dependencies = [ - "itertools", - "phoenix-api", - "rand 0.8.5", - "serde", -] - [[package]] name = "phoenix-api-policy-hello-acl" version = "0.1.0" @@ -2045,174 +1975,6 @@ dependencies = [ "toml", ] -[[package]] -name = "phoenix-genaclserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genaclserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genfaultserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genfaultserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genloggingserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genloggingserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genmetricsserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genmetricsserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genmutationserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genmutationserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genratelimitclient" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genratelimitclient", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - -[[package]] -name = "phoenix-genratelimitserver" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "futures", - "itertools", - "minstant", - "mrpc-derive", - "mrpc-marshal", - "nix", - "phoenix-api", - "phoenix-api-policy-genratelimitserver", - "phoenix_common", - "rand 0.8.5", - "serde", - "serde_json", - "shm", - "thiserror", - "toml", -] - [[package]] name = "phoenix-hello-acl" version = "0.1.0" diff --git a/experimental/mrpc/Cargo.toml b/experimental/mrpc/Cargo.toml index ede410cd..8c3d8d3f 100644 --- a/experimental/mrpc/Cargo.toml +++ b/experimental/mrpc/Cargo.toml @@ -4,30 +4,22 @@ version = "0.1.0" edition = "2021" [features] -timing = [ - "dep:minstant", -] +timing = ["dep:minstant"] [dependencies.phoenix-api-mrpc] workspace = true [dependencies.phoenix-api] workspace = true -features = [ - "mrpc", -] +features = ["mrpc"] [dependencies.ipc] workspace = true -features = [ - "customer", -] +features = ["customer"] [dependencies.shm] workspace = true -features = [ - "mrpc", -] +features = ["mrpc"] [dependencies.mmap] workspace = true @@ -156,62 +148,8 @@ members = [ "examples/masstree_analytics", "examples/hotel_reservation", "examples/load_balancer", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitclient", - "generated/plugin/genratelimitclient", - "generated/api/genratelimitserver", - "generated/plugin/genratelimitserver", - "generated/api/genloggingserver", - "generated/plugin/genloggingserver", - "generated/api/genloggingserver", - "generated/plugin/genloggingserver", - "generated/api/genmutationserver", - "generated/plugin/genmutationserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genmetricsserver", - "generated/plugin/genmetricsserver", - "generated/api/genfaultserver", - "generated/plugin/genfaultserver", - "generated/api/genfaultserver", - "generated/plugin/genfaultserver", - "generated/api/genfaultserver", - "generated/plugin/genfaultserver", - "generated/api/genfaultserver", - "generated/plugin/genfaultserver", - "generated/api/genfaultserver", - "generated/plugin/genfaultserver", - "generated/api/genaclserver", - "generated/plugin/genaclserver", -] -exclude = [ - "3rdparty/prost", ] +exclude = ["3rdparty/prost"] [workspace.dependencies] thiserror = "1.0.31" @@ -406,26 +344,5 @@ package = "phoenix-salloc" [workspace.dependencies.utils] path = "../../src/utils" -[workspace.dependencies.phoenix-api-policy-genratelimitclient] -path = "generated/api/genratelimitclient" - -[workspace.dependencies.phoenix-api-policy-genratelimitserver] -path = "generated/api/genratelimitserver" - -[workspace.dependencies.phoenix-api-policy-genloggingserver] -path = "generated/api/genloggingserver" - -[workspace.dependencies.phoenix-api-policy-genmutationserver] -path = "generated/api/genmutationserver" - -[workspace.dependencies.phoenix-api-policy-genmetricsserver] -path = "generated/api/genmetricsserver" - -[workspace.dependencies.phoenix-api-policy-genfaultserver] -path = "generated/api/genfaultserver" - -[workspace.dependencies.phoenix-api-policy-genaclserver] -path = "generated/api/genaclserver" - [profile.release] debug = true