diff options
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 46 | ||||
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | src/call/server.rs | 20 | ||||
-rw-r--r-- | src/channel.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/server.rs | 39 |
10 files changed, 96 insertions, 34 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 43ff69f..c4d77c4 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "4112a2249ebaa7a354cf59179979e3b4b08a077f" + "sha1": "37188956eb8e71631326d708b8afb0940918f5d8" } } @@ -25,44 +25,44 @@ rust_library { // bindgen-0.51.1 // bitflags-1.2.1 "default" // boringssl-src-0.1.0 -// cc-1.0.62 +// cc-1.0.66 // cexpr-0.3.6 // cfg-if-0.1.10 // cfg-if-1.0.0 // clang-sys-0.28.1 "clang_6_0,gte_clang_3_6,gte_clang_3_7,gte_clang_3_8,gte_clang_3_9,gte_clang_4_0,gte_clang_5_0,gte_clang_6_0,libloading,runtime" -// cmake-0.1.44 -// futures-0.3.7 "alloc,async-await,default,executor,futures-executor,std" -// futures-channel-0.3.7 "alloc,futures-sink,sink,std" -// futures-core-0.3.7 "alloc,std" -// futures-executor-0.3.7 "std" -// futures-io-0.3.7 "std" -// futures-macro-0.3.7 -// futures-sink-0.3.7 "alloc,std" -// futures-task-0.3.7 "alloc,once_cell,std" -// futures-util-0.3.7 "alloc,async-await,async-await-macro,channel,futures-channel,futures-io,futures-macro,futures-sink,io,memchr,proc-macro-hack,proc-macro-nested,sink,slab,std" +// cmake-0.1.45 +// futures-0.3.8 "alloc,async-await,default,executor,futures-executor,std" +// futures-channel-0.3.8 "alloc,futures-sink,sink,std" +// futures-core-0.3.8 "alloc,std" +// futures-executor-0.3.8 "std" +// futures-io-0.3.8 "std" +// futures-macro-0.3.8 +// futures-sink-0.3.8 "alloc,std" +// futures-task-0.3.8 "alloc,once_cell,std" +// futures-util-0.3.8 "alloc,async-await,async-await-macro,channel,futures-channel,futures-io,futures-macro,futures-sink,io,memchr,proc-macro-hack,proc-macro-nested,sink,slab,std" // glob-0.3.0 -// grpcio-sys-0.7.1 "default" -// instant-0.1.8 +// grpcio-sys-0.7.2 "default" +// instant-0.1.9 // lazy_static-1.4.0 -// libc-0.2.80 "default,std" +// libc-0.2.81 "default,std" // libloading-0.5.2 // libz-sys-1.1.2 "default,libc,static,stock-zlib" -// lock_api-0.4.1 +// lock_api-0.4.2 // log-0.4.11 // memchr-2.3.4 "default,std,use_std" // nom-4.2.3 "alloc,default,std,verbose-errors" -// once_cell-1.4.1 "std" -// parking_lot-0.11.0 "default" -// parking_lot_core-0.8.0 +// once_cell-1.5.2 "alloc,std" +// parking_lot-0.11.1 "default" +// parking_lot_core-0.8.1 // peeking_take_while-0.1.2 -// pin-project-1.0.1 -// pin-project-internal-1.0.1 +// pin-project-1.0.2 +// pin-project-internal-1.0.2 // pin-utils-0.1.0 // pkg-config-0.3.19 // proc-macro-hack-0.5.19 // proc-macro-nested-0.1.6 // proc-macro2-1.0.24 "default,proc-macro" -// protobuf-2.18.0 +// protobuf-2.18.1 // quote-1.0.7 "default,proc-macro" // regex-1.4.2 "aho-corasick,default,memchr,perf,perf-cache,perf-dfa,perf-inline,perf-literal,std,thread_local,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment" // regex-syntax-0.6.21 "default,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment" @@ -71,8 +71,8 @@ rust_library { // scopeguard-1.1.0 // shlex-0.1.1 // slab-0.4.2 -// smallvec-1.4.2 -// syn-1.0.48 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut" +// smallvec-1.5.1 +// syn-1.0.54 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut" // thread_local-1.0.1 // unicode-xid-0.2.1 "default" // version_check-0.1.5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 65a0e8c..6a6dfdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.7.1 - 2020-12-18 + +- Allow CXX environment variable to override g++ for musl build (#500) +- Add user-defined checker for server side (#502) + # 0.7.0 - 2020-11-02 - Add blocking callback to `EnvBuilder` (#474) @@ -13,7 +13,7 @@ [package] edition = "2018" name = "grpcio" -version = "0.7.0" +version = "0.7.1" authors = ["The TiKV Project Developers"] autoexamples = false description = "The rust language implementation of gRPC, base on the gRPC c core library." diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 18457aa..7daa61e 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "grpcio" -version = "0.7.0" +version = "0.7.1" edition = "2018" authors = ["The TiKV Project Developers"] license = "Apache-2.0" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/grpcio/grpcio-0.7.0.crate" + value: "https://static.crates.io/crates/grpcio/grpcio-0.7.1.crate" } - version: "0.7.0" + version: "0.7.1" license_type: NOTICE last_upgrade_date { year: 2020 - month: 11 - day: 8 + month: 12 + day: 18 } } diff --git a/src/call/server.rs b/src/call/server.rs index add9874..875555e 100644 --- a/src/call/server.rs +++ b/src/call/server.rs @@ -25,8 +25,10 @@ use crate::codec::{DeserializeFn, SerializeFn}; use crate::cq::CompletionQueue; use crate::error::{Error, Result}; use crate::metadata::Metadata; +use crate::server::ServerChecker; use crate::server::{BoxHandler, RequestCallContext}; use crate::task::{BatchFuture, CallTag, Executor, Kicker}; +use crate::CheckResult; pub struct Deadline { spec: gpr_timespec, @@ -74,12 +76,13 @@ impl RequestContext { cq: &CompletionQueue, rc: &mut RequestCallContext, ) -> result::Result<(), Self> { + let checker = rc.get_checker(); let handler = unsafe { rc.get_handler(self.method()) }; match handler { Some(handler) => match handler.method_type() { MethodType::Unary | MethodType::ServerStreaming => Err(self), _ => { - execute(self, cq, None, handler); + execute(self, cq, None, handler, checker); Ok(()) } }, @@ -225,9 +228,10 @@ impl UnaryRequestContext { cq: &CompletionQueue, reader: Option<MessageReader>, ) { + let checker = rc.get_checker(); let handler = unsafe { rc.get_handler(self.request.method()).unwrap() }; if reader.is_some() { - return execute(self.request, cq, reader, handler); + return execute(self.request, cq, reader, handler, checker); } let status = RpcStatus::new(RpcStatusCode::INTERNAL, Some("No payload".to_owned())); @@ -775,7 +779,19 @@ fn execute( cq: &CompletionQueue, payload: Option<MessageReader>, f: &mut BoxHandler, + mut checkers: Vec<Box<dyn ServerChecker>>, ) { let rpc_ctx = RpcContext::new(ctx, cq); + + for handler in checkers.iter_mut() { + match handler.check(&rpc_ctx) { + CheckResult::Continue => {} + CheckResult::Abort(status) => { + rpc_ctx.call().abort(&status); + return; + } + } + } + f.handle(rpc_ctx, payload) } diff --git a/src/channel.rs b/src/channel.rs index bdf95ce..a33a4be 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -28,7 +28,7 @@ pub use crate::grpc_sys::{ /// Ref: http://www.grpc.io/docs/guides/wire.html#user-agents fn format_user_agent_string(agent: &str) -> CString { - let version = "0.7.0"; + let version = "0.7.1"; let trimed_agent = agent.trim(); let val = if trimed_agent.is_empty() { format!("grpc-rust/{}", version) @@ -77,4 +77,6 @@ pub use crate::security::{ CertificateRequestType, ChannelCredentials, ChannelCredentialsBuilder, ServerCredentials, ServerCredentialsBuilder, ServerCredentialsFetcher, }; -pub use crate::server::{Server, ServerBuilder, Service, ServiceBuilder, ShutdownFuture}; +pub use crate::server::{ + CheckResult, Server, ServerBuilder, ServerChecker, Service, ServiceBuilder, ShutdownFuture, +}; diff --git a/src/server.rs b/src/server.rs index 8cb6a87..0f01690 100644 --- a/src/server.rs +++ b/src/server.rs @@ -21,6 +21,7 @@ use crate::env::Environment; use crate::error::{Error, Result}; use crate::task::{CallTag, CqFuture}; use crate::RpcContext; +use crate::RpcStatus; const DEFAULT_REQUEST_SLOTS_PER_CQ: usize = 1024; @@ -266,6 +267,24 @@ impl ServiceBuilder { } } +/// Used to indicate the result of the check. If it returns `Abort`, +/// skip the subsequent checkers and abort the grpc call. +pub enum CheckResult { + Continue, + Abort(RpcStatus), +} + +pub trait ServerChecker: Send { + fn check(&mut self, ctx: &RpcContext) -> CheckResult; + fn box_clone(&self) -> Box<dyn ServerChecker>; +} + +impl Clone for Box<dyn ServerChecker> { + fn clone(&self) -> Self { + self.box_clone() + } +} + /// A gRPC service. /// /// Use [`ServiceBuilder`] to build a [`Service`]. @@ -280,6 +299,7 @@ pub struct ServerBuilder { args: Option<ChannelArgs>, slots_per_cq: usize, handlers: HashMap<&'static [u8], BoxHandler>, + checkers: Vec<Box<dyn ServerChecker>>, } impl ServerBuilder { @@ -291,6 +311,7 @@ impl ServerBuilder { args: None, slots_per_cq: DEFAULT_REQUEST_SLOTS_PER_CQ, handlers: HashMap::new(), + checkers: Vec::new(), } } @@ -320,6 +341,16 @@ impl ServerBuilder { self } + /// Add a custom checker to handle some tasks before the grpc call handler starts. + /// This allows users to operate grpc call based on the context. Users can add + /// multiple checkers and they will be executed in the order added. + /// + /// TODO: Extend this interface to intercepte each payload like grpc-c++. + pub fn add_checker<C: ServerChecker + 'static>(mut self, checker: C) -> ServerBuilder { + self.checkers.push(Box::new(checker)); + self + } + /// Finalize the [`ServerBuilder`] and build the [`Server`]. pub fn build(mut self) -> Result<Server> { let args = self @@ -355,6 +386,7 @@ impl ServerBuilder { slots_per_cq: self.slots_per_cq, }), handlers: self.handlers, + checkers: self.checkers, }) } } @@ -439,6 +471,7 @@ pub type BoxHandler = Box<dyn CloneableHandler>; pub struct RequestCallContext { server: Arc<ServerCore>, registry: Arc<UnsafeCell<HashMap<&'static [u8], BoxHandler>>>, + checkers: Vec<Box<dyn ServerChecker>>, } impl RequestCallContext { @@ -449,6 +482,10 @@ impl RequestCallContext { let registry = &mut *self.registry.get(); registry.get_mut(path) } + + pub(crate) fn get_checker(&self) -> Vec<Box<dyn ServerChecker>> { + self.checkers.clone() + } } // Apparently, its life time is guaranteed by the ref count, hence is safe to be sent @@ -506,6 +543,7 @@ pub struct Server { env: Arc<Environment>, core: Arc<ServerCore>, handlers: HashMap<&'static [u8], BoxHandler>, + checkers: Vec<Box<dyn ServerChecker>>, } impl Server { @@ -549,6 +587,7 @@ impl Server { let rc = RequestCallContext { server: self.core.clone(), registry: Arc::new(UnsafeCell::new(registry)), + checkers: self.checkers.clone(), }; for _ in 0..self.core.slots_per_cq { request_call(rc.clone(), cq); |