-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[wip, feat] Action dispatcher state machine
Signed-off-by: dd di cesare <[email protected]>
- Loading branch information
1 parent
ed8eec1
commit 51bb020
Showing
2 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#[derive(PartialEq, Debug, Clone)] | ||
enum State { | ||
Pending, | ||
Waiting, | ||
Done, | ||
} | ||
|
||
impl State { | ||
fn next(&mut self) { | ||
match self { | ||
State::Pending => *self = State::Waiting, | ||
State::Waiting => *self = State::Done, | ||
_ => {} | ||
} | ||
} | ||
} | ||
#[derive(PartialEq, Clone)] | ||
enum Action { | ||
Auth { state: State }, | ||
RateLimit { state: State }, | ||
} | ||
|
||
impl Action { | ||
pub fn trigger(&mut self) { | ||
match self { | ||
Action::Auth { .. } => self.auth(), | ||
Action::RateLimit { .. } => self.rate_limit(), | ||
} | ||
} | ||
|
||
fn get_state(&self) -> &State { | ||
match self { | ||
Action::Auth { state } => state, | ||
Action::RateLimit { state } => state, | ||
} | ||
} | ||
|
||
fn rate_limit(&mut self) { | ||
// Specifics for RL, returning State | ||
if let Action::RateLimit { state } = self { | ||
match state { | ||
State::Pending => { | ||
println!("Trigger the request and return State::Waiting"); | ||
state.next(); | ||
} | ||
State::Waiting => { | ||
println!( | ||
"When got on_grpc_response, process RL response and return State::Done" | ||
); | ||
state.next(); | ||
} | ||
State::Done => { | ||
println!("Done for RL... calling next action (?)"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn auth(&mut self) { | ||
// Specifics for Auth, returning State | ||
if let Action::Auth { state } = self { | ||
match state { | ||
State::Pending => { | ||
println!("Trigger the request and return State::Waiting"); | ||
state.next(); | ||
} | ||
State::Waiting => { | ||
println!( | ||
"When got on_grpc_response, process Auth response and return State::Done" | ||
); | ||
state.next(); | ||
} | ||
State::Done => { | ||
println!("Done for Auth... calling next action (?)"); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub struct ActionDispatcher { | ||
actions: Vec<Action>, | ||
} | ||
|
||
impl ActionDispatcher { | ||
pub fn default() -> ActionDispatcher { | ||
ActionDispatcher { actions: vec![] } | ||
} | ||
|
||
pub fn new(/*vec of PluginConfig actions*/) -> ActionDispatcher { | ||
ActionDispatcher::default() | ||
} | ||
|
||
pub fn next(&mut self) -> bool { | ||
if let Some((i, action)) = self.actions.iter_mut().enumerate().next() { | ||
if let State::Done = action.get_state() { | ||
self.actions.remove(i); | ||
self.actions.len() > 0 | ||
} else { | ||
action.trigger(); | ||
true | ||
} | ||
} else { | ||
false | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn action_transition() { | ||
let mut action = Action::Auth { | ||
state: State::Pending, | ||
}; | ||
assert_eq!(*action.get_state(), State::Pending); | ||
action.trigger(); | ||
assert_eq!(*action.get_state(), State::Waiting); | ||
action.trigger(); | ||
assert_eq!(*action.get_state(), State::Done); | ||
} | ||
|
||
#[test] | ||
fn action_dispatcher_next() { | ||
let mut action_dispatcher = ActionDispatcher{ | ||
actions: vec![ | ||
Action::RateLimit {state: State::Pending} | ||
], | ||
}; | ||
let mut res = action_dispatcher.next(); | ||
let mut binding = action_dispatcher.actions.clone(); | ||
let mut current_action_state = binding.first().unwrap().get_state(); | ||
|
||
assert_eq!(res, true); | ||
assert_eq!(*current_action_state, State::Waiting); | ||
|
||
res = action_dispatcher.next(); | ||
binding = action_dispatcher.actions.clone(); | ||
current_action_state = binding.first().unwrap().get_state(); | ||
|
||
assert_eq!(res, true); | ||
assert_eq!(*current_action_state, State::Done); | ||
|
||
res = action_dispatcher.next(); | ||
assert_eq!(res, false); | ||
assert_eq!(action_dispatcher.actions.len(), 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod action_dispatcher; | ||
mod attribute; | ||
mod configuration; | ||
mod envoy; | ||
|