diff --git a/crates/xline/src/server/command.rs b/crates/xline/src/server/command.rs index cd564729d..dc201ff8e 100644 --- a/crates/xline/src/server/command.rs +++ b/crates/xline/src/server/command.rs @@ -15,6 +15,7 @@ use parking_lot::RwLock; use tracing::warn; use utils::{barrier::IdBarrier, table_names::META_TABLE}; use xlineapi::{ + classifier::RequestClassifier, command::{Command, CurpClient, SyncResponse}, execute_error::ExecuteError, AlarmAction, AlarmRequest, AlarmType, @@ -22,7 +23,7 @@ use xlineapi::{ use crate::{ revision_number::RevisionNumberGeneratorState, - rpc::{RequestBackend, RequestWrapper}, + rpc::RequestWrapper, storage::{ db::{WriteOp, DB}, index::IndexOperate, @@ -315,22 +316,22 @@ impl CommandExecutor { I: IndexOperate, { let er = to_execute - .then(|| match wrapper.backend() { - RequestBackend::Auth => self.auth_storage.execute(wrapper), - RequestBackend::Lease => self.lease_storage.execute(wrapper), - RequestBackend::Alarm => Ok(self.alarm_storage.execute(wrapper)), - RequestBackend::Kv => unreachable!("Should not execute kv commands"), + .then(|| match wrapper { + x if x.is_auth_backend() => self.auth_storage.execute(wrapper), + x if x.is_lease_backend() => self.lease_storage.execute(wrapper), + x if x.is_alarm_backend() => Ok(self.alarm_storage.execute(wrapper)), + _ => unreachable!("Should not execute kv commands"), }) .transpose()?; - let (asr, wr_ops) = match wrapper.backend() { - RequestBackend::Auth => self.auth_storage.after_sync(wrapper, auth_revision)?, - RequestBackend::Lease => { + let (asr, wr_ops) = match wrapper { + x if x.is_auth_backend() => self.auth_storage.after_sync(wrapper, auth_revision)?, + x if x.is_lease_backend() => { self.lease_storage .after_sync(wrapper, general_revision, txn_db, index)? } - RequestBackend::Alarm => self.alarm_storage.after_sync(wrapper, general_revision), - RequestBackend::Kv => unreachable!("Should not sync kv commands"), + x if x.is_alarm_backend() => self.alarm_storage.after_sync(wrapper, general_revision), + _ => unreachable!("Should not sync kv commands"), }; txn_db.write_ops(wr_ops)?; @@ -421,11 +422,12 @@ impl CurpCommandExecutor for CommandExecutor { let auth_info = cmd.auth_info(); let wrapper = cmd.request(); self.auth_storage.check_permission(wrapper, auth_info)?; - match wrapper.backend() { - RequestBackend::Kv => self.kv_storage.execute(wrapper, None), - RequestBackend::Auth => self.auth_storage.execute(wrapper), - RequestBackend::Lease => self.lease_storage.execute(wrapper), - RequestBackend::Alarm => Ok(self.alarm_storage.execute(wrapper)), + match &wrapper { + x if x.is_kv_backend() => self.kv_storage.execute(wrapper, None), + x if x.is_auth_backend() => self.auth_storage.execute(wrapper), + x if x.is_lease_backend() => self.lease_storage.execute(wrapper), + x if x.is_alarm_backend() => Ok(self.alarm_storage.execute(wrapper)), + _ => unreachable!("Must be one of kv, auth, lease, alarm"), } } @@ -438,11 +440,12 @@ impl CurpCommandExecutor for CommandExecutor { > { let er = self.execute(cmd)?; let wrapper = cmd.request(); - let rev = match wrapper.backend() { - RequestBackend::Kv | RequestBackend::Lease | RequestBackend::Alarm => { + let rev = match wrapper { + x if x.is_auth_backend() => self.auth_storage.revision_gen().get(), + x if (x.is_kv_backend() || x.is_lease_backend() || x.is_alarm_backend()) => { self.kv_storage.revision_gen().get() } - RequestBackend::Auth => self.auth_storage.revision_gen().get(), + _ => unreachable!("Must be one of kv, auth, lease, alarm"), }; Ok((er, SyncResponse::new(rev))) } @@ -484,15 +487,15 @@ impl CurpCommandExecutor for CommandExecutor { states.update_result(|c| { let (cmd, to_execute) = c.into_parts(); let wrapper = cmd.request(); - let (asr, er) = match wrapper.backend() { - RequestBackend::Kv => self.after_sync_kv( + let (asr, er) = match wrapper { + x if x.is_kv_backend() => self.after_sync_kv( wrapper, &txn_db, &index_state, &general_revision_state, to_execute, ), - RequestBackend::Auth | RequestBackend::Lease | RequestBackend::Alarm => self + x if x.is_auth_backend() || x.is_lease_backend() || x.is_alarm_backend() => self .after_sync_others( wrapper, &txn_db, @@ -501,6 +504,7 @@ impl CurpCommandExecutor for CommandExecutor { &auth_revision_state, to_execute, ), + _ => unreachable!("Must be one of kv, auth, lease, alarm"), }?; if let RequestWrapper::CompactionRequest(ref compact_req) = *wrapper { diff --git a/crates/xlineapi/src/classifier.rs b/crates/xlineapi/src/classifier.rs new file mode 100644 index 000000000..89ab66eca --- /dev/null +++ b/crates/xlineapi/src/classifier.rs @@ -0,0 +1,141 @@ +use super::RequestWrapper; + +pub trait RequestClassifier { + fn is_kv_backend(&self) -> bool; + fn is_lease_backend(&self) -> bool; + fn is_auth_backend(&self) -> bool; + fn is_alarm_backend(&self) -> bool; + fn is_put(&self) -> bool; + fn is_compaction(&self) -> bool; + fn is_txn(&self) -> bool; + fn is_range(&self) -> bool; + fn is_read_only(&self) -> bool; + fn is_write(&self) -> bool; +} + +/// because RequestWrapper do not repr u8, we need to convert it manually. +impl From<&RequestWrapper> for u8 { + fn from(value: &RequestWrapper) -> Self { + match *value { + RequestWrapper::PutRequest(_) => 0, + RequestWrapper::RangeRequest(_) => 1, + RequestWrapper::DeleteRangeRequest(_) => 2, + RequestWrapper::TxnRequest(_) => 3, + RequestWrapper::CompactionRequest(_) => 4, + RequestWrapper::AuthEnableRequest(_) => 5, + RequestWrapper::AuthDisableRequest(_) => 6, + RequestWrapper::AuthStatusRequest(_) => 7, + RequestWrapper::AuthRoleAddRequest(_) => 8, + RequestWrapper::AuthRoleDeleteRequest(_) => 9, + RequestWrapper::AuthRoleGetRequest(_) => 10, + RequestWrapper::AuthRoleGrantPermissionRequest(_) => 11, + RequestWrapper::AuthRoleListRequest(_) => 12, + RequestWrapper::AuthRoleRevokePermissionRequest(_) => 13, + RequestWrapper::AuthUserAddRequest(_) => 14, + RequestWrapper::AuthUserChangePasswordRequest(_) => 15, + RequestWrapper::AuthUserDeleteRequest(_) => 16, + RequestWrapper::AuthUserGetRequest(_) => 17, + RequestWrapper::AuthUserGrantRoleRequest(_) => 18, + RequestWrapper::AuthUserListRequest(_) => 19, + RequestWrapper::AuthUserRevokeRoleRequest(_) => 20, + RequestWrapper::AuthenticateRequest(_) => 21, + RequestWrapper::LeaseGrantRequest(_) => 22, + RequestWrapper::LeaseRevokeRequest(_) => 23, + RequestWrapper::LeaseLeasesRequest(_) => 24, + RequestWrapper::AlarmRequest(_) => 25, + } + } +} + +impl RequestClassifier for RequestWrapper { + #[inline] + fn is_kv_backend(&self) -> bool { + matches!( + *self, + RequestWrapper::PutRequest(_) + | RequestWrapper::RangeRequest(_) + | RequestWrapper::DeleteRangeRequest(_) + | RequestWrapper::TxnRequest(_) + | RequestWrapper::CompactionRequest(_) + ) + } + #[inline] + fn is_auth_backend(&self) -> bool { + matches!( + self, + RequestWrapper::AuthEnableRequest(_) + | RequestWrapper::AuthDisableRequest(_) + | RequestWrapper::AuthStatusRequest(_) + | RequestWrapper::AuthRoleAddRequest(_) + | RequestWrapper::AuthRoleDeleteRequest(_) + | RequestWrapper::AuthRoleGetRequest(_) + | RequestWrapper::AuthRoleGrantPermissionRequest(_) + | RequestWrapper::AuthRoleListRequest(_) + | RequestWrapper::AuthRoleRevokePermissionRequest(_) + | RequestWrapper::AuthUserAddRequest(_) + | RequestWrapper::AuthUserChangePasswordRequest(_) + | RequestWrapper::AuthUserDeleteRequest(_) + | RequestWrapper::AuthUserGetRequest(_) + | RequestWrapper::AuthUserGrantRoleRequest(_) + | RequestWrapper::AuthUserListRequest(_) + | RequestWrapper::AuthUserRevokeRoleRequest(_) + | RequestWrapper::AuthenticateRequest(_) + ) + } + #[inline] + fn is_lease_backend(&self) -> bool { + matches!( + self, + RequestWrapper::LeaseGrantRequest(_) + | RequestWrapper::LeaseRevokeRequest(_) + | RequestWrapper::LeaseLeasesRequest(_) + ) + } + #[inline] + fn is_alarm_backend(&self) -> bool { + matches!(self, RequestWrapper::AlarmRequest(_)) + } + #[inline] + fn is_put(&self) -> bool { + matches!(self, RequestWrapper::PutRequest(_)) + } + #[inline] + fn is_range(&self) -> bool { + matches!( + self, + RequestWrapper::RangeRequest(_) | RequestWrapper::DeleteRangeRequest(_) + ) + } + #[inline] + fn is_txn(&self) -> bool { + matches!(self, RequestWrapper::TxnRequest(_)) + } + #[inline] + fn is_compaction(&self) -> bool { + matches!(self, RequestWrapper::CompactionRequest(_)) + } + + #[inline] + /// Read only request + fn is_read_only(&self) -> bool { + matches!( + self, + RequestWrapper::RangeRequest(_) + | RequestWrapper::AuthStatusRequest(_) + | RequestWrapper::AuthRoleGetRequest(_) + | RequestWrapper::AuthRoleListRequest(_) + | RequestWrapper::AuthUserGetRequest(_) + | RequestWrapper::AuthUserListRequest(_) + | RequestWrapper::LeaseLeasesRequest(_) + ) + } + + #[inline] + /// Write request. + /// + /// NOTE: A `TxnRequest` or a `DeleteRangeRequest` might be read-only, but we + /// assume they will mutate the state machine to simplify the implementation. + fn is_write(&self) -> bool { + !self.is_read_only() + } +} diff --git a/crates/xlineapi/src/command.rs b/crates/xlineapi/src/command.rs index ecbd37231..c34c92ba9 100644 --- a/crates/xlineapi/src/command.rs +++ b/crates/xlineapi/src/command.rs @@ -1,5 +1,6 @@ use std::{ - collections::HashSet, + cell::RefCell, + collections::{HashMap, HashSet}, ops::{Bound, RangeBounds}, }; @@ -10,8 +11,8 @@ use prost::Message; use serde::{Deserialize, Serialize}; use crate::{ - execute_error::ExecuteError, AuthInfo, PbCommand, PbCommandResponse, PbKeyRange, - PbSyncResponse, RequestWrapper, ResponseWrapper, + classifier::RequestClassifier, execute_error::ExecuteError, AuthInfo, PbCommand, + PbCommandResponse, PbKeyRange, PbSyncResponse, RequestWrapper, ResponseWrapper, }; /// The curp client trait object on the command of xline @@ -24,6 +25,11 @@ const UNBOUNDED: &[u8] = &[0_u8]; /// Range end to get one key const ONE_KEY: &[u8] = &[]; +thread_local! { + /// A global cache to store conflict rules. The rules will not change, so it's safe to use a global cache. + static CONFLICT_RULES_CACHE: RefCell> = RefCell::new(HashMap::new()); +} + /// Key Range for Command #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)] pub struct KeyRange { @@ -222,67 +228,130 @@ pub struct Command { auth_info: Option, } -impl ConflictCheck for Command { - #[inline] - fn is_conflict(&self, other: &Self) -> bool { - let this_req = &self.request; - let other_req = &other.request; - // auth read request will not conflict with any request except the auth write request - if (this_req.is_auth_read_request() && other_req.is_auth_read_request()) - || (this_req.is_kv_request() && other_req.is_auth_read_request()) - || (this_req.is_auth_read_request() && other_req.is_kv_request()) - { - return false; - } - // any two requests that don't meet the above conditions will conflict with each other - // because the auth write request will make all previous token invalid - if this_req.is_auth_request() - || other_req.is_auth_request() - || this_req.is_alarm_request() - || other_req.is_alarm_request() - { - return true; - } +/// Match all Classifiers separated by `&` +/// +/// # Returns +/// +/// `Fn(x) -> bool` indicates the match result. +/// +/// # Example +/// +/// ```ignore +/// match_all!(is_auth_backend & is_put)(x) +/// ``` +macro_rules! match_all { + ($($func:ident)&*) => { + |_x: &RequestWrapper| $(_x.$func())&&* + }; +} - // Lease leases request is conflict with Lease grant and revoke requests - if (this_req.is_lease_read_request() && other_req.is_lease_write_request()) - || (this_req.is_lease_write_request() && other_req.is_lease_read_request()) - { - return true; +/// swapable match, returns a `Fn(x, y) -> bool` indicates the match result. +/// +/// # Returns +/// +/// Returns `Fn(x, y) -> true` if *x match Classifier1 and y match Classifier2*, +/// or *x match Classifier2 and y match Classifier1*. +macro_rules! swap_match { + ($($func:ident)&*, _) => {{ + |_x, _| match_all!($($func)&*)(_x) + }}; + ($($func1:ident)&*, $($func2:ident)&*) => { + |_x, _y| { + (match_all!($($func1)&*)(_x) && match_all!($($func2)&*)(_y)) || ( + match_all!($($func2)&*)(_x) && match_all!($($func1)&*)(_y) + ) } + }; +} - if this_req.is_compaction_request() && other_req.is_compaction_request() { - return true; - } +/// swapable map, to swappable match two `RequestWrapper`, extract the inner request +/// and calculate the inners into an `Option`. +/// This can be only used in the same enum and different variant. +/// +/// # Returns +/// +/// `Fn(x, y) -> Option` indicates the swap_map result. +macro_rules! swap_map { + ($cls1:ident :: $tag1:ident, $cls2:ident :: $tag2:ident, |$x:ident, $y:ident| $body:expr) => { + (|_self, _other| match (_self, _other) { + (&$cls1::$tag1(ref $x), &$cls2::$tag2(ref $y)) + | (&$cls2::$tag2(ref $y), &$cls1::$tag1(ref $x)) => Some($body), + _ => None, + }) + }; +} - if (this_req.is_txn_request() && other_req.is_compaction_request()) - || (this_req.is_compaction_request() && other_req.is_txn_request()) - { - match (this_req, other_req) { - ( - &RequestWrapper::CompactionRequest(ref com_req), - &RequestWrapper::TxnRequest(ref txn_req), - ) - | ( - &RequestWrapper::TxnRequest(ref txn_req), - &RequestWrapper::CompactionRequest(ref com_req), - ) => { - let target_revision = com_req.revision; - return txn_req.is_conflict_with_rev(target_revision) - } - _ => unreachable!("The request must be either a transaction or a compaction request! \nthis_req = {this_req:?} \nother_req = {other_req:?}") - } +/// Conflict check, contains the whole `match` statement +/// +/// # Returns +/// +/// `Fn(x, y) -> Option` indicates the conflict result. +macro_rules! is_conflict { + ($(($body:expr, $($func:ident)&*, $($pat:tt)*)),*) => { + |_self, _other| match (_self, _other) { + $((x, y) if swap_match!($($func)&*, $($pat)*)(x, y) => Some($body),)* + _ => None, } + }; +} - let this_lease_ids = this_req.leases().into_iter().collect::>(); - let other_lease_ids = other_req.leases().into_iter().collect::>(); - let lease_conflict = !this_lease_ids.is_disjoint(&other_lease_ids); - let key_conflict = self - .keys() - .iter() - .cartesian_product(other.keys().iter()) - .any(|(k1, k2)| k1.is_conflicted(k2)); - lease_conflict || key_conflict +impl ConflictCheck for Command { + #[inline] + fn is_conflict(&self, other: &Self) -> bool { + let t_req = &self.request; + let o_req = &other.request; + let mut cache_key: (u8, u8) = (t_req.into(), o_req.into()); + if cache_key.0 > cache_key.1 { + cache_key = (cache_key.1, cache_key.0); + } + if let Some(res) = CONFLICT_RULES_CACHE.with_borrow(|x| x.get(&cache_key).cloned()) { + return res; + } + let first_step = is_conflict!( + // auth read request will not conflict with any request except the auth write request + ( + true, + is_auth_backend & is_read_only, + is_auth_backend & is_write + ), + (false, is_auth_backend & is_read_only, _), + // any two requests that don't meet the above conditions will conflict with each other + // because the auth write request will make all previous token invalid + (true, is_auth_backend & is_write, _), + (true, is_alarm_backend, _), + // Lease leases request is conflict with Lease grant and revoke requests + ( + true, + is_lease_backend & is_read_only, + is_lease_backend & is_write + ), + (true, is_compaction, is_compaction) + )(t_req, o_req); + if let Some(first_step_res) = first_step { + CONFLICT_RULES_CACHE + .with_borrow_mut(|x| x.insert((t_req.into(), o_req.into()), first_step_res)); + } + first_step + .or_else(|| { + swap_map!( + RequestWrapper::TxnRequest, + RequestWrapper::CompactionRequest, + |x, y| x.is_conflict_with_rev(y.revision) + )(t_req, o_req) + }) + // the fallback map + .or_else(|| { + let this_lease_ids = t_req.leases().into_iter().collect::>(); + let other_lease_ids = o_req.leases().into_iter().collect::>(); + let lease_conflict = !this_lease_ids.is_disjoint(&other_lease_ids); + let key_conflict = self + .keys() + .iter() + .cartesian_product(other.keys().iter()) + .any(|(k1, k2)| k1.is_conflict(k2)); + Some(lease_conflict || key_conflict) + }) + .unwrap_or_default() } } @@ -516,9 +585,9 @@ impl PbCodec for Command { mod test { use super::*; use crate::{ - AuthEnableRequest, AuthStatusRequest, CommandAttr, CompactionRequest, Compare, - DeleteRangeRequest, LeaseGrantRequest, LeaseLeasesRequest, LeaseRevokeRequest, PutRequest, - PutResponse, RangeRequest, Request, RequestOp, TxnRequest, + AlarmRequest, AuthEnableRequest, AuthStatusRequest, CommandAttr, CompactionRequest, + Compare, DeleteRangeRequest, LeaseGrantRequest, LeaseLeasesRequest, LeaseRevokeRequest, + PutRequest, PutResponse, RangeRequest, Request, RequestOp, TxnRequest, }; #[test] @@ -553,6 +622,22 @@ mod test { assert!(!kr4.contains_key(b"e")); } + #[test] + fn test_cache_should_work() { + let cmd1 = Command::new(RequestWrapper::AuthStatusRequest(AuthStatusRequest { + ..Default::default() + })); + let cmd2 = Command::new(RequestWrapper::AlarmRequest(AlarmRequest { + ..Default::default() + })); + let cache_key = ((&cmd1.request).into(), (&cmd2.request).into()); + if CONFLICT_RULES_CACHE.with_borrow(|x| x.get(&cache_key).is_some()) { + return; + } + let _ig = ConflictCheck::is_conflict(&cmd1, &cmd2); + assert!(CONFLICT_RULES_CACHE.with_borrow(|x| x.get(&cache_key).is_some())); + } + #[test] fn test_command_conflict() { let cmd1 = Command::new(RequestWrapper::DeleteRangeRequest(DeleteRangeRequest { diff --git a/crates/xlineapi/src/lib.rs b/crates/xlineapi/src/lib.rs index 1b88bb8e6..aa2f1ca4e 100644 --- a/crates/xlineapi/src/lib.rs +++ b/crates/xlineapi/src/lib.rs @@ -172,6 +172,7 @@ ) )] +pub mod classifier; pub mod command; pub mod execute_error; pub mod interval; @@ -207,6 +208,7 @@ mod errorpb { use std::fmt::Display; +use classifier::RequestClassifier; use command::KeyRange; use utils::write_vec; @@ -317,19 +319,6 @@ impl ResponseWrapper { } } -/// Backend store of request -#[derive(Debug, PartialEq, Eq)] -pub enum RequestBackend { - /// Kv backend - Kv, - /// Auth backend - Auth, - /// Lease backend - Lease, - /// Alarm backend - Alarm, -} - /// Command attributes pub trait CommandAttr { /// Key ranges @@ -454,89 +443,9 @@ impl RequestWrapper { } } - /// Get the backend of the request - pub fn backend(&self) -> RequestBackend { - match *self { - RequestWrapper::PutRequest(_) - | RequestWrapper::RangeRequest(_) - | RequestWrapper::DeleteRangeRequest(_) - | RequestWrapper::TxnRequest(_) - | RequestWrapper::CompactionRequest(_) => RequestBackend::Kv, - RequestWrapper::AuthEnableRequest(_) - | RequestWrapper::AuthDisableRequest(_) - | RequestWrapper::AuthStatusRequest(_) - | RequestWrapper::AuthRoleAddRequest(_) - | RequestWrapper::AuthRoleDeleteRequest(_) - | RequestWrapper::AuthRoleGetRequest(_) - | RequestWrapper::AuthRoleGrantPermissionRequest(_) - | RequestWrapper::AuthRoleListRequest(_) - | RequestWrapper::AuthRoleRevokePermissionRequest(_) - | RequestWrapper::AuthUserAddRequest(_) - | RequestWrapper::AuthUserChangePasswordRequest(_) - | RequestWrapper::AuthUserDeleteRequest(_) - | RequestWrapper::AuthUserGetRequest(_) - | RequestWrapper::AuthUserGrantRoleRequest(_) - | RequestWrapper::AuthUserListRequest(_) - | RequestWrapper::AuthUserRevokeRoleRequest(_) - | RequestWrapper::AuthenticateRequest(_) => RequestBackend::Auth, - RequestWrapper::LeaseGrantRequest(_) - | RequestWrapper::LeaseRevokeRequest(_) - | RequestWrapper::LeaseLeasesRequest(_) => RequestBackend::Lease, - RequestWrapper::AlarmRequest(_) => RequestBackend::Alarm, - } - } - - /// Checks if this request is read only - /// - /// NOTE: A `TxnRequest` or a `DeleteRangeRequest` might be read-only, but we - /// assume they will mutate the state machine to simplify the implementation. - pub fn is_read_only(&self) -> bool { - match *self { - RequestWrapper::RangeRequest(_) - | RequestWrapper::AuthStatusRequest(_) - | RequestWrapper::AuthRoleGetRequest(_) - | RequestWrapper::AuthRoleListRequest(_) - | RequestWrapper::AuthUserGetRequest(_) - | RequestWrapper::AuthUserListRequest(_) - | RequestWrapper::LeaseLeasesRequest(_) => true, - - RequestWrapper::PutRequest(_) - | RequestWrapper::DeleteRangeRequest(_) - | RequestWrapper::TxnRequest(_) - | RequestWrapper::CompactionRequest(_) - | RequestWrapper::AuthEnableRequest(_) - | RequestWrapper::AuthDisableRequest(_) - | RequestWrapper::AuthRoleAddRequest(_) - | RequestWrapper::AuthRoleDeleteRequest(_) - | RequestWrapper::AuthRoleGrantPermissionRequest(_) - | RequestWrapper::AuthRoleRevokePermissionRequest(_) - | RequestWrapper::AuthUserAddRequest(_) - | RequestWrapper::AuthUserChangePasswordRequest(_) - | RequestWrapper::AuthUserDeleteRequest(_) - | RequestWrapper::AuthUserGrantRoleRequest(_) - | RequestWrapper::AuthUserRevokeRoleRequest(_) - | RequestWrapper::AuthenticateRequest(_) - | RequestWrapper::LeaseGrantRequest(_) - | RequestWrapper::LeaseRevokeRequest(_) - | RequestWrapper::AlarmRequest(_) => false, - } - } - - /// Check if this request is a auth read request - pub fn is_auth_read_request(&self) -> bool { - matches!( - *self, - RequestWrapper::AuthStatusRequest(_) - | RequestWrapper::AuthRoleGetRequest(_) - | RequestWrapper::AuthRoleListRequest(_) - | RequestWrapper::AuthUserGetRequest(_) - | RequestWrapper::AuthUserListRequest(_) - ) - } - /// Check whether this auth request should skip the revision or not pub fn skip_auth_revision(&self) -> bool { - self.is_auth_read_request() + self.is_read_only() || matches!( *self, RequestWrapper::AuthEnableRequest(_) | RequestWrapper::AuthenticateRequest(_) @@ -558,39 +467,6 @@ impl RequestWrapper { _ => false, } } - - /// Check if this request is a auth request - pub fn is_auth_request(&self) -> bool { - self.backend() == RequestBackend::Auth - } - - /// Check if this request is a kv request - pub fn is_kv_request(&self) -> bool { - self.backend() == RequestBackend::Kv - } - - pub fn is_compaction_request(&self) -> bool { - matches!(*self, RequestWrapper::CompactionRequest(_)) - } - - pub fn is_txn_request(&self) -> bool { - matches!(*self, RequestWrapper::TxnRequest(_)) - } - - pub fn is_lease_read_request(&self) -> bool { - matches!(*self, RequestWrapper::LeaseLeasesRequest(_)) - } - - pub fn is_lease_write_request(&self) -> bool { - matches!( - *self, - RequestWrapper::LeaseGrantRequest(_) | RequestWrapper::LeaseRevokeRequest(_) - ) - } - - pub fn is_alarm_request(&self) -> bool { - matches!(*self, RequestWrapper::AlarmRequest(_)) - } } /// impl `From` trait for all request types