Skip to content

Commit

Permalink
Fix the error of duplicate signing within multiple threads
Browse files Browse the repository at this point in the history
  • Loading branch information
henry42 committed May 17, 2024
1 parent b0eb7d5 commit a261169
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl Signer {
F: FnOnce(&str) -> T,
{
if self.is_expired() {
self.renew()?;
self.renew_if_expired()?;
}

let signature = self.signature.read();
Expand Down Expand Up @@ -175,7 +175,7 @@ impl Signer {
))
}

fn renew(&self) -> Result<(), Error> {
fn renew_if_expired(&self) -> Result<(), Error> {
let issued_at = get_time();

#[cfg(feature = "tracing")]
Expand All @@ -191,10 +191,12 @@ impl Signer {

let mut signature = self.signature.write();

*signature = Signature {
key: Self::create_signature(&self.secret, &self.key_id, &self.team_id, issued_at)?,
issued_at,
};
if get_time() - signature.issued_at >= self.expire_after_s.as_secs() as i64 {
*signature = Signature {
key: Self::create_signature(&self.secret, &self.key_id, &self.team_id, issued_at)?,
issued_at,
};
}

Ok(())
}
Expand Down Expand Up @@ -248,6 +250,8 @@ fn get_time() -> i64 {

#[cfg(test)]
mod tests {
use std::{collections::HashSet, sync::Mutex, time::Instant};

use super::*;

const PRIVATE_KEY: &str = "-----BEGIN PRIVATE KEY-----
Expand Down Expand Up @@ -293,4 +297,53 @@ jDwmlD1Gg0yJt1e38djFwsxsfr5q2hv0Rj9fTEqAPr8H7mGm0wKxZ7iQ

assert_ne!(sig1, sig2);
}

#[test]
fn test_signature_caching_in_multithreads() {
let signer = Signer::new(
PRIVATE_KEY.as_bytes(),
"89AFRD1X22",
"ASDFQWERTY",
Duration::from_secs(3),
)
.unwrap();

let signer = Arc::new(signer);

let created_sign: Arc<Mutex<HashSet<String>>> = Arc::new(Mutex::new(HashSet::new()));
let mut threads = Vec::new();
let now = Instant::now();

for _ in 0..100 {
let created_sign = created_sign.clone();
let now = now.clone();
let signer = signer.clone();
threads.push(std::thread::spawn(move || {

let mut sig = String::new();
loop {
let mut sig1 = String::new();
signer.with_signature(|sig| sig1.push_str(sig)).unwrap();

if sig1 != sig {
sig = sig1.clone();
let mut created_sign = created_sign.lock().unwrap();
created_sign.insert(sig1);
}

if now.elapsed() > Duration::from_secs(4) {
break;
}

}

}));
}

for th in threads {
let _ = th.join();
}

assert_eq!(created_sign.lock().unwrap().len() , 2);
}
}

0 comments on commit a261169

Please sign in to comment.