reworked counter
This commit is contained in:
parent
890fe56a16
commit
f5a16766d6
4 changed files with 101 additions and 84 deletions
172
src/counter.rs
172
src/counter.rs
|
@ -4,7 +4,8 @@ use actix::prelude::*;
|
|||
use derive_builder::Builder;
|
||||
//use lazy_static::*;
|
||||
|
||||
use crate::levels::Levels;
|
||||
use crate::new_levels::Defense;
|
||||
//use crate::new_levels::Levels;
|
||||
|
||||
// TODO move this into config parameter
|
||||
// lazy_static! {
|
||||
|
@ -22,27 +23,48 @@ struct DeleteVisitor;
|
|||
|
||||
#[derive(Builder)]
|
||||
pub struct Counter {
|
||||
visitor_count: usize,
|
||||
levels: Levels,
|
||||
#[builder(default = "0", setter(skip))]
|
||||
visitor_count: u32,
|
||||
defense: Defense,
|
||||
duration: u64,
|
||||
}
|
||||
|
||||
impl Default for Counter {
|
||||
fn default() -> Self {
|
||||
Counter {
|
||||
visitor_count: 0,
|
||||
levels: Levels::default(),
|
||||
duration: 30,
|
||||
// impl Default for Counter {
|
||||
// fn default() -> Self {
|
||||
// Counter {
|
||||
// visitor_count: 0,
|
||||
// levels: Levels::default(),
|
||||
// duration: 30,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Counter {
|
||||
/// incerment visiotr count by one
|
||||
pub fn add_visitor(&mut self) {
|
||||
self.visitor_count += 1;
|
||||
if self.visitor_count > self.defense.visitor_threshold() {
|
||||
self.defense.tighten_up();
|
||||
} else {
|
||||
self.defense.loosen_up();
|
||||
}
|
||||
}
|
||||
|
||||
/// deccerment visiotr count by one
|
||||
pub fn decrement_visiotr(&mut self) {
|
||||
if self.visitor_count > 0 {
|
||||
self.visitor_count -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// get current difficulty factor
|
||||
pub fn get_difficulty(&self) -> u32 {
|
||||
self.defense.get_difficulty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for Counter {
|
||||
type Context = Context<Self>;
|
||||
|
||||
// fn started(&mut self, ctx: &mut Self::Context) {
|
||||
// ctx.set_mailbox_capacity(usize::MAX / 2);
|
||||
// }
|
||||
}
|
||||
|
||||
impl Handler<Visitor> for Counter {
|
||||
|
@ -50,8 +72,6 @@ impl Handler<Visitor> for Counter {
|
|||
fn handle(&mut self, _: Visitor, ctx: &mut Self::Context) -> Self::Result {
|
||||
use actix::clock::delay_for;
|
||||
|
||||
self.visitor_count += 1;
|
||||
|
||||
let addr = ctx.address();
|
||||
|
||||
let duration: Duration = Duration::new(self.duration.clone(), 0);
|
||||
|
@ -62,97 +82,93 @@ impl Handler<Visitor> for Counter {
|
|||
.into_actor(self);
|
||||
ctx.spawn(wait_for);
|
||||
|
||||
if self.visitor_count > self.levels.threshold() {
|
||||
self.levels.focus();
|
||||
} else {
|
||||
self.levels.relax();
|
||||
}
|
||||
|
||||
self.levels.get_difficulty()
|
||||
self.add_visitor();
|
||||
self.get_difficulty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<DeleteVisitor> for Counter {
|
||||
type Result = ();
|
||||
fn handle(&mut self, _msg: DeleteVisitor, _ctx: &mut Self::Context) -> Self::Result {
|
||||
if self.visitor_count > 0 {
|
||||
self.visitor_count -= 1;
|
||||
}
|
||||
self.decrement_visiotr();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::new_levels::*;
|
||||
|
||||
async fn race(addr: Addr<Counter>, count: Levels) {
|
||||
for _ in 0..count as usize - 1 {
|
||||
// constants foor testing
|
||||
// (visitor count, level)
|
||||
const LEVEL_1: (u32, u32) = (50, 50);
|
||||
const LEVEL_2: (u32, u32) = (500, 500);
|
||||
const DURATION: u64 = 10;
|
||||
|
||||
fn get_defense() -> Defense {
|
||||
DefenseBuilder::default()
|
||||
.add_level(
|
||||
LevelBuilder::default()
|
||||
.visitor_count(LEVEL_1.0)
|
||||
.difficulty_factor(LEVEL_1.1)
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
.add_level(
|
||||
LevelBuilder::default()
|
||||
.visitor_count(LEVEL_2.0)
|
||||
.difficulty_factor(LEVEL_2.1)
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn race(addr: Addr<Counter>, count: (u32, u32)) {
|
||||
for _ in 0..count.0 as usize - 1 {
|
||||
let _ = addr.send(Visitor).await.unwrap();
|
||||
}
|
||||
}
|
||||
#[actix_rt::test]
|
||||
async fn counter_focus_works() {
|
||||
let four = Levels::Four.get_difficulty();
|
||||
let three = Levels::Three.get_difficulty();
|
||||
let two = Levels::Two.get_difficulty();
|
||||
let one = Levels::One.get_difficulty();
|
||||
|
||||
let addr = Counter::default().start();
|
||||
|
||||
let mut difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, one);
|
||||
|
||||
let addr = Counter::default().start();
|
||||
race(addr.clone(), Levels::One).await;
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, one);
|
||||
|
||||
let addr = Counter::default().start();
|
||||
race(addr.clone(), Levels::Two).await;
|
||||
addr.send(Visitor).await.unwrap();
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, two);
|
||||
|
||||
let addr = Counter::default().start();
|
||||
race(addr.clone(), Levels::Three).await;
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, three);
|
||||
|
||||
let addr = Counter::default().start();
|
||||
race(addr.clone(), Levels::Four).await;
|
||||
addr.send(Visitor).await.unwrap();
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, four);
|
||||
fn get_counter() -> Counter {
|
||||
CounterBuilder::default()
|
||||
.defense(get_defense())
|
||||
.duration(DURATION)
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn counter_relax_works() {
|
||||
use actix::clock::delay_for;
|
||||
let four = Levels::Four.get_difficulty();
|
||||
let three = Levels::Three.get_difficulty();
|
||||
let two = Levels::Two.get_difficulty();
|
||||
let one = Levels::One.get_difficulty();
|
||||
|
||||
let addr = Counter::default().start();
|
||||
async fn counter_defense_tightenup_works() {
|
||||
let addr = get_counter().start();
|
||||
|
||||
let mut difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, LEVEL_1.0);
|
||||
|
||||
let addr = Counter::default().start();
|
||||
race(addr.clone(), Levels::Four).await;
|
||||
addr.send(Visitor).await.unwrap();
|
||||
race(addr.clone(), LEVEL_2).await;
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, four);
|
||||
assert_eq!(difficulty_factor, LEVEL_2.1);
|
||||
}
|
||||
|
||||
// could break when default duration for counter actor changes
|
||||
let duration = Duration::new(30, 0);
|
||||
#[actix_rt::test]
|
||||
async fn counter_defense_loosenup_works() {
|
||||
use actix::clock::delay_for;
|
||||
let addr = get_counter().start();
|
||||
|
||||
race(addr.clone(), LEVEL_2).await;
|
||||
race(addr.clone(), LEVEL_2).await;
|
||||
let mut difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, LEVEL_2.1);
|
||||
|
||||
let duration = Duration::new(DURATION, 0);
|
||||
delay_for(duration).await;
|
||||
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, three);
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, two);
|
||||
difficulty_factor = addr.send(Visitor).await.unwrap();
|
||||
assert_eq!(difficulty_factor, one);
|
||||
assert_eq!(difficulty_factor, LEVEL_1.1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
//! Error datatypes
|
||||
use derive_more::{Display, Error};
|
||||
|
||||
/// Errors that can occur when interacting with the blockchain
|
||||
/// Errors that can occur when using
|
||||
#[derive(Debug, PartialEq, Display, Clone, Error)]
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub enum CaptchaError {
|
||||
/// when configuring m_captcha, `DefenseBuilder` must be passed atleast
|
||||
/// when configuring m_captcha, [DefenseBuilder][crate::new_levels::DefenseBuilder] must be passed atleast
|
||||
/// one `LevelConfig` if not this error will arise
|
||||
#[display(fmt = "LevelBuilder should have atleaset one level configured")]
|
||||
LevelEmpty,
|
||||
|
||||
/// Visitor count must be an integer
|
||||
/// when configuring m_captcha, `LevelBuilder` difficulty_factor
|
||||
/// when configuring m_captcha, [LevelBuilder][crate::new_levels::LevelBuilder] difficulty_factor
|
||||
/// must be set to greater than zero.
|
||||
#[display(fmt = "difficulty factor must be greater than zero")]
|
||||
DifficultyFactorZero,
|
||||
|
||||
/// Difficulty factor must be set
|
||||
#[display(fmt = "Set difficulty factor")]
|
||||
SetDifficultyFactor,
|
||||
|
||||
/// Visitor count must be set
|
||||
#[display(fmt = "Set visitor count")]
|
||||
SetVisitorCount,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pub mod counter;
|
||||
pub mod errors;
|
||||
mod levels;
|
||||
mod new_levels;
|
||||
pub mod new_levels;
|
||||
|
|
|
@ -177,10 +177,8 @@ impl Defense {
|
|||
/// tighten up defense. Increases defense level by a factor of one
|
||||
/// when defense is at max level, calling this method will have no effect
|
||||
pub fn tighten_up(&mut self) {
|
||||
println!("{}", self.current_visitor_threshold);
|
||||
if self.current_visitor_threshold != self.levels.len() - 1 {
|
||||
self.current_visitor_threshold += 1;
|
||||
println!("{}", self.current_visitor_threshold);
|
||||
}
|
||||
}
|
||||
/// loosen up defense. Decreases defense level by a factor of one
|
||||
|
|
Loading…
Reference in a new issue