-
Notifications
You must be signed in to change notification settings - Fork 0
add child manager aggregation logic #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v0
Are you sure you want to change the base?
Conversation
| // work_requests: Arc<Mutex<HashSet<Arc<T>>>>, | ||
| // work_scheduler: Arc<dyn WorkScheduler>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please delete all commented-out code.
| fn resolve_child_controller( | ||
| &mut self, | ||
| channel_controller: WrappedController, | ||
| channel_controller: &mut WrappedController, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please configure your editor to remove trailing whitespaces on save. And/or make sure you are running rustfmt (which I would expect would do that, too).
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting-wise, please make sure to follow some standard practices, e.g. just one blank line between functions, no double-blank lines in the middle of a function, no blank lines between closing braces, etc.
| } | ||
|
|
||
| pub trait ChildIdentifier: PartialEq + Hash + Eq + Send + Sync + 'static {} | ||
| use std::{sync::{atomic::{AtomicUsize, Ordering}}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should go above where the other use statements are.
| pub trait ChildIdentifier: PartialEq + Hash + Eq + Send + Sync + 'static {} | ||
| use std::{sync::{atomic::{AtomicUsize, Ordering}}}; | ||
|
|
||
| pub trait ChildIdentifier: PartialEq + Hash + Eq + Send + Sync + Display + 'static {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know that we want to enforce child identifiers to implement Display... Debug should be sufficient.
| // } | ||
| } | ||
|
|
||
| fn compare_prev_to_new_pickers(& self, old_pickers: &[Arc<dyn Picker>], new_pickers: &[Arc<dyn Picker>]) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to do this... We can just always produce an update if any child updated. That should be good enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will look into it! I remember that I was running into an issue with updated not being reliable which is why I added this but I definitely could have missed something
| } | ||
|
|
||
| fn exit_idle(&mut self, channel_controller: &mut dyn ChannelController) { | ||
| todo!() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call all children and exit_idle them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh huh I wrote this but somehow didn't make it into the commit...
| } | ||
| } | ||
|
|
||
| struct ReadyPickers { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have just one RoundRobinPicker that holds these same fields?
| pub fn new() -> Self { | ||
| Self { | ||
| pickers: vec![], | ||
| next: AtomicUsize::new(0), | ||
| } | ||
| } | ||
|
|
||
| fn add_picker(&mut self, picker: Arc<dyn Picker>) { | ||
| self.pickers.push(picker); | ||
| } | ||
|
|
||
| pub fn has_any(&self) -> bool { | ||
| !self.pickers.is_empty() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, it would simplify if you only have a new(v: Vec<Arc<dyn Picker>>).
|
|
||
| impl Picker for SchedulingIdlePicker { | ||
| fn pick(&self, _request: &Request) -> PickResult { | ||
| self.work_scheduler.schedule_work(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe this special case is needed. When you call into the idle picker of the child, it should be responsible for requesting work if it needs it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes will delete.
| sent_connecting_state: bool, | ||
| aggregated_state: ConnectivityState, | ||
| last_ready_pickers: Vec<Arc<dyn Picker>>, | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove extraneous blank lines. Blank lines should be intentionally visually separating things.
| pub fn new( | ||
| update_sharder: Box<dyn ResolverUpdateSharder<T>> | ||
| ) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't need to get reformatted. How are you running rustfmt?
| pub fn new( | ||
| update_sharder: Box<dyn ResolverUpdateSharder<T>> | ||
| ) -> Self { | ||
| ChildManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ChildManager { | |
| Self { |
I think is preferred, as it was before.
| // let mut transient_failure_picker = TransientFailurePickers::new("error string I guess".to_string()); | ||
| // let mut connecting_pickers = ConnectingPickers::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out code should always be removed.
a76ed88 to
1bdeab1
Compare
| } | ||
|
|
||
| /// Called to aggregate states from children policies then returns a update. | ||
| pub fn aggregate_states(&mut self) -> Option<LbState> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this an Option? I would think it should always return a valid LbState, even if it's "TRANSIENT_FAILURE, "
| let should_update = | ||
| !self.compare_prev_to_new_pickers(&self.last_ready_pickers, &pickers_vec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this exist? I thought this function would just produce the aggregate state / aggregate picker, always. Why wouldn't it want to do that?
| prev_state: ConnectivityState::Idle, | ||
| last_ready_pickers: Vec::new(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of state, I think, should generally be kept in a policy that uses the child manager nad not in the child manager itself.
| } | ||
|
|
||
| fn exit_idle(&mut self, channel_controller: &mut dyn ChannelController) { | ||
| let child_idxes = mem::take(&mut *self.pending_work.lock().unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't right. We want to call exit_idle on all children (or all idle children?) if this happens. Not just the ones that have requested work (which should be none of the idle ones).
|
|
||
| fn update_picker(&mut self, update: LbState) { | ||
| self.picker_update = Some(update); | ||
| self.picker_update = Some(update.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
| fn add_picker(&mut self, picker: Arc<dyn Picker>) { | ||
| self.pickers.push(picker); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make it so all the pickers are known when new is called instead?
Ideally we set next initially to a random value in the range of the number of entries.
| if len == 0 { | ||
| return PickResult::Queue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this special case be handled by having a queuing picker instead, and not using this with empty lists?
Add child manager aggregation logic
@dfawley @easwars