Skip to content

Commit

Permalink
chore: Optimize the performance of read-write locks
Browse files Browse the repository at this point in the history
  • Loading branch information
andeya committed Oct 15, 2024
1 parent e0d6c17 commit ff4d25f
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn main() {

let a = FileAdapter::new("examples/rbac_with_pattern_policy.csv");

let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), |_req, _depot| {
let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), false, |_req, _depot| {
Ok(Some(CasbinVals {
subject: String::from("alice"),
domain: None,
Expand Down
61 changes: 26 additions & 35 deletions src/hoop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct CasbinVals {
#[derive(Clone)]
pub struct CasbinHoop<E, F> {
enforcer: Arc<RwLock<E>>,
use_enforcer_mut: bool,
get_casbin_vals: F,
}
impl<E, F> Deref for CasbinHoop<E, F> {
Expand All @@ -40,14 +41,15 @@ where
+ Sync
+ 'static,
{
pub fn new(enforcer: E, get_casbin_vals: F) -> Self {
pub fn new(enforcer: E, use_enforcer_mut: bool, get_casbin_vals: F) -> Self {
CasbinHoop {
enforcer: Arc::new(RwLock::new(enforcer)),
use_enforcer_mut,
get_casbin_vals,
}
}

pub fn get_enforcer(&mut self) -> Arc<RwLock<E>> {
pub fn get_enforcer(&self) -> Arc<RwLock<E>> {
self.enforcer.clone()
}

Expand Down Expand Up @@ -75,40 +77,29 @@ where
let path = req.uri().path().to_string();
let action = req.method().as_str().to_string();

if !vals.subject.is_empty() {
if let Some(domain) = vals.domain {
let mut lock = self.enforcer.write().await;
match lock.enforce_mut(vec![vals.subject, domain, path, action]) {
Ok(true) => {
drop(lock);
}
Ok(false) => {
drop(lock);
res.render(StatusError::forbidden());
}
Err(_) => {
drop(lock);
res.render(StatusError::bad_gateway());
}
}
} else {
let mut lock = self.enforcer.write().await;
match lock.enforce_mut(vec![vals.subject, path, action]) {
Ok(true) => {
drop(lock);
}
Ok(false) => {
drop(lock);
res.render(StatusError::forbidden());
}
Err(_) => {
drop(lock);
res.render(StatusError::bad_gateway());
}
}
}
} else {
if vals.subject.is_empty() {
res.render(StatusError::unauthorized());
return;
}

let rvals = if let Some(domain) = vals.domain {
vec![vals.subject, domain, path, action]
} else {
vec![vals.subject, path, action]
};
let r = if self.use_enforcer_mut {
self.enforcer.write().await.enforce_mut(rvals)
} else {
self.enforcer.read().await.enforce(rvals)
};
match r {
Ok(true) => {}
Ok(false) => {
res.render(StatusError::forbidden());
}
Err(_) => {
res.render(StatusError::bad_gateway());
}
}
}
}
2 changes: 1 addition & 1 deletion tests/test_hoop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async fn test_hoop() {

let a = FileAdapter::new("examples/rbac_with_pattern_policy.csv");

let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), |_req, _depot| {
let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), false, |_req, _depot| {
Ok(Some(CasbinVals {
subject: String::from("alice"),
domain: None,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hoop_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ async fn test_hoop_domain() {
.unwrap();
let a = FileAdapter::new("examples/rbac_with_domains_policy.csv");

let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), |_req, _depot| {
let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), false, |_req, _depot| {
Ok(Some(CasbinVals {
subject: String::from("alice"),
domain: Some(String::from("domain1")),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_set_enforcer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn test_set_enforcer() {
.unwrap();
let a = FileAdapter::new("examples/rbac_with_pattern_policy.csv");

let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), |_req, _depot| {
let casbin_hoop = CasbinHoop::new(Enforcer::new(m, a).await.unwrap(), false,|_req, _depot| {
Ok(Some(CasbinVals {
subject: String::from("alice"),
domain: None,
Expand Down

0 comments on commit ff4d25f

Please sign in to comment.