Use RwLock
This commit is contained in:
parent
adcc18f5a5
commit
7abe487918
2 changed files with 26 additions and 24 deletions
|
@ -1,12 +1,22 @@
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::RwLock;
|
||||||
|
|
||||||
struct CaptchaSolutions {
|
struct CaptchaSolutions {
|
||||||
last_id: u16,
|
last_id: u16,
|
||||||
solutions: Vec<Option<String>>,
|
solutions: Vec<Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CaptchaSolutions {
|
||||||
|
fn get_sol(&self, id: u16) -> &Option<String> {
|
||||||
|
&self.solutions[id as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_sol(&mut self, id: u16, sol: Option<String>) {
|
||||||
|
self.solutions[id as usize] = sol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SharedCaptchaSolutions {
|
pub struct SharedCaptchaSolutions {
|
||||||
arc: Arc<Mutex<CaptchaSolutions>>,
|
inner: RwLock<CaptchaSolutions>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SharedCaptchaSolutions {
|
impl Default for SharedCaptchaSolutions {
|
||||||
|
@ -16,42 +26,33 @@ impl Default for SharedCaptchaSolutions {
|
||||||
solutions.resize(max_size, None);
|
solutions.resize(max_size, None);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
arc: Arc::new(Mutex::new(CaptchaSolutions {
|
inner: RwLock::new(CaptchaSolutions {
|
||||||
last_id: 0,
|
last_id: 0,
|
||||||
solutions,
|
solutions,
|
||||||
})),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedCaptchaSolutions {
|
impl SharedCaptchaSolutions {
|
||||||
fn lock(&self) -> MutexGuard<CaptchaSolutions> {
|
pub fn store_sol(&self, sol: String) -> u16 {
|
||||||
self.arc.lock().unwrap()
|
let mut captcha_solutions = self.inner.write().unwrap();
|
||||||
}
|
|
||||||
|
|
||||||
pub fn store_solution(&self, solution: &str) -> u16 {
|
|
||||||
let mut captcha_solutions = self.lock();
|
|
||||||
|
|
||||||
let new_id = captcha_solutions.last_id.wrapping_add(1);
|
let new_id = captcha_solutions.last_id.wrapping_add(1);
|
||||||
captcha_solutions.last_id = new_id;
|
captcha_solutions.last_id = new_id;
|
||||||
|
|
||||||
captcha_solutions.solutions[new_id as usize] = Some(solution.to_string());
|
captcha_solutions.set_sol(new_id, Some(sol));
|
||||||
|
|
||||||
new_id
|
new_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_answer(&self, id: u16, answer: &str) -> bool {
|
pub fn check_answer(&self, id: u16, answer: &str) -> bool {
|
||||||
{
|
if *self.inner.read().unwrap().get_sol(id) != Some(answer.trim().to_string()) {
|
||||||
let mut captcha_solutions = self.lock();
|
return false;
|
||||||
|
|
||||||
let id = id as usize;
|
|
||||||
|
|
||||||
if captcha_solutions.solutions[id] == Some(answer.trim().to_string()) {
|
|
||||||
captcha_solutions.solutions[id] = None;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
self.inner.write().unwrap().set_sol(id, None);
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub async fn index(
|
||||||
State(captcha_solutions): State<Arc<captcha_solutions::SharedCaptchaSolutions>>,
|
State(captcha_solutions): State<Arc<captcha_solutions::SharedCaptchaSolutions>>,
|
||||||
) -> Result<Response, errors::AppError> {
|
) -> Result<Response, errors::AppError> {
|
||||||
info!("Visited get(index)");
|
info!("Visited get(index)");
|
||||||
|
|
||||||
render_contact_form(IndexParams {
|
render_contact_form(IndexParams {
|
||||||
config,
|
config,
|
||||||
captcha_solutions,
|
captcha_solutions,
|
||||||
|
@ -41,9 +42,9 @@ pub async fn render_contact_form(params: IndexParams<'_>) -> Result<Response, er
|
||||||
let captcha = captcha::by_name(captcha::Difficulty::Easy, captcha::CaptchaName::Lucy);
|
let captcha = captcha::by_name(captcha::Difficulty::Easy, captcha::CaptchaName::Lucy);
|
||||||
let captcha_base64 = captcha.as_base64().context("Failed to create a captcha!")?;
|
let captcha_base64 = captcha.as_base64().context("Failed to create a captcha!")?;
|
||||||
|
|
||||||
let id = params
|
let solution = captcha.chars_as_string();
|
||||||
.captcha_solutions
|
|
||||||
.store_solution(&captcha.chars_as_string());
|
let id = params.captcha_solutions.store_sol(solution);
|
||||||
|
|
||||||
let template = templates::ContactForm {
|
let template = templates::ContactForm {
|
||||||
base: templates::Base {
|
base: templates::Base {
|
||||||
|
|
Loading…
Reference in a new issue