You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extract shared get_up_windows helper for window scanning
Extract get_window_cpu_average_vector for CPU averaging
Reuse helpers in recycler and manager computations
Reset up flag each iteration, fixing stale state
Diagram Walkthrough
flowchart LR
A["get_recycler_count"] -- "above HUBER_THRESHOLD" --> C["get_up_windows"]
B["manager count logic"] -- "below MANAGER_SLOPE" --> C
C -- "per-window averages" --> D["get_window_cpu_average_vector"]
Loading
File Walkthrough
Relevant files
Enhancement
flow_threads.rs
Unify recycler and manager window computation logic
src/flow_threads.rs
Added generic get_up_windows function unifying the duplicated window-scanning loops from recycler and manager computations, parameterized by threshold and above
Added get_window_cpu_average_vector helper for per-window CPU usage averaging
Simplified get_recycler_count and manager count logic to consume the new helpers
Reset up flag at each loop iteration fixing stale state across windows; fixed misplaced brace and added trailing newline
The manager computation previously verified that average CPU usage exceeded CPU_USAGE_MAX for each window element before marking a window as "up" (if avg > CPU_USAGE_MAX { up &= true; } else { up &= false; break; }). The new unified get_up_windows helper only checks the slope threshold, so this CPU check is silently removed from the manager path. As a result, windows where the flow manager CPU is low are now accepted as long as the slope is below MANAGER_SLOPE, which can change mgr_power and the resulting manager count. The now-unused avg variable in the loop confirms the check was lost rather than intentionally relocated.
get_up_windows advances counter until current_windows.last() matches one of the last three elements of result, relying on value equality of f64 samples. If no window's last element matches (e.g., monotonically increasing queue values where the final samples differ from earlier ones), result[(counter*WINDOWS) as usize..((counter+1)*WINDOWS) as usize] will eventually index past the end of result and panic. This existed in the previous code, but the refactor consolidates it into a shared helper now used by both the recycler and manager paths, so both call sites are exposed.
current_windows = result[(counter*WINDOWS)asusize..((counter+1)*WINDOWS)asusize].to_vec();for current_window in¤t_windows {let avg:f32 = avg_cpu_usage[(sm_counter *(avg_cpu_usage.len()/WINDOWSasusize)) ..
((sm_counter + 1)*(avg_cpu_usage.len()/WINDOWSasusize))].iter().sum::<f32>() / (avg_cpu_usage.len()/WINDOWSasusize)asf32;
sm_counter+=1;if(above && current_window > &threshold) || (!above && current_window < &threshold){
tmp_slope_vector.push(*current_window);
up &= true;}else{
up &= false;break;}if avg > CPU_USAGE_MAX{
up &= true;}else{
up &= false;break;}}
sm_counter=0;if up {
up_windows.push((counter, tmp_slope_vector.clone()));}let last_three = result.iter().rev().take(3).collect::<Vec<_>>();if last_three.contains(¤t_windows.last().expect("Unable to get last element from current_window vector.")){break;}
counter +=1;
Add bounds check to prevent index-out-of-bounds panic
*The loop termination relies on a fragile exact f64 equality check against the last three elements of result. If that condition never matches, counter grows until the slice result[(counter*WINDOWS)..((counter+1)WINDOWS)] panics with an index-out-of-bounds error. Add an explicit bounds check at the top of the loop to guarantee termination.
loop {
+ if ((counter + 1) * WINDOWS) as usize > result.len() {+ break;+ }
avg_cpu_usage = Self::get_window_cpu_average_vector(cpu_usages, num_elements, counter);
current_windows = result[(counter*WINDOWS) as usize..((counter+1)*WINDOWS) as usize].to_vec();
Suggestion importance[1-10]: 7
__
Why: The loop's termination depends on a fragile float-equality check, and if it fails to trigger, the slice result[(counter*WINDOWS)..((counter+1)*WINDOWS)] can panic with an out-of-bounds error. Adding an explicit bounds check is a valid defensive fix for a real potential panic, though the existing termination logic usually covers the aligned case.
Medium
Guard against division by zero producing NaN
If get_up_windows returns an entry with an empty tmp_slope_vector (possible when a window slice is empty and up stays true), the division by tmp_slope_vector.len() produces NaN, which then propagates into mgr_power and the module result. Skip empty vectors before computing the average.
for (_counter, tmp_slope_vector) in Self::get_up_windows(&flow_mgr_full_result, &mgr_cpu_usages, num_elements, MANAGER_SLOPE, false) {
- slope_vector.push(tmp_slope_vector.iter().sum::<f64>() / tmp_slope_vector.len() as f64);+ if !tmp_slope_vector.is_empty() {+ slope_vector.push(tmp_slope_vector.iter().sum::<f64>() / tmp_slope_vector.len() as f64);+ }
}
Suggestion importance[1-10]: 5
__
Why: An empty tmp_slope_vector would produce NaN via division by zero, which would then propagate into mgr_power. The guard is correct but somewhat defensive since tmp_slope_vector is normally non-empty when up_windows entries are created; it is a minor robustness improvement.
Low
Handle empty stat vectors to avoid NaN averages
If now_in_queue or now_recycled is empty (e.g., now_recycled has fewer than 2 elements before the .windows(2) diff), the division by zero yields NaN for the averages, which poisons slope_vector and the subsequent max_by comparison. Fall back to 0.0 when the vectors are empty.
- recycler_up.now_in_queue_avg = now_in_queue.iter().sum::<f64>() / now_in_queue.len() as f64;- recycler_up.now_recycled_avg = now_recycled.iter().sum::<f64>() / now_recycled.len() as f64;+ recycler_up.now_in_queue_avg = if now_in_queue.is_empty() { 0.0 } else { now_in_queue.iter().sum::<f64>() / now_in_queue.len() as f64 };+ recycler_up.now_recycled_avg = if now_recycled.is_empty() { 0.0 } else { now_recycled.iter().sum::<f64>() / now_recycled.len() as f64 };
slope_vector.push(recycler_up);
Suggestion importance[1-10]: 4
__
Why: Guarding against empty now_in_queue/now_recycled avoids NaN averages, but these slices are derived from fixed-size index ranges that are expected to be non-empty, and silently defaulting to 0.0 could mask underlying data issues. It is a low-impact defensive change.
Low
General
Replace fragile float-equality loop termination
The termination condition compares floating-point values for exact equality, which is unreliable for regression output and may never trigger (leading to unbounded counter growth). Additionally, current_windows.last() panics if the slice is empty. Compare slice indices/ranges instead of element values, e.g., break when the remaining tail of result is exhausted.
let last_three = result.iter().rev().take(3).collect::<Vec<_>>();
- if last_three.contains(¤t_windows.last().expect("Unable to get last element from current_window vector.")) {+ if last_three.contains(current_windows.last().unwrap_or(&0.0)) {
break;
}
+ if result.len() - (counter as usize * WINDOWS as usize) < WINDOWS as usize {+ break;+ }+
Suggestion importance[1-10]: 4
__
Why: The concern about exact f64 equality for loop termination and the potential panic on current_windows.last() is valid, but the improved_code does not fully implement the suggestion — it retains the float-equality check and merely adds a bounds check and unwrap_or, so it only partially addresses the described problem.
Low
Author self-review: I have reviewed the PR code suggestions, and addressed the relevant ones.
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Type
Enhancement, Bug fix
Description
Extract shared
get_up_windowshelper for window scanningExtract
get_window_cpu_average_vectorfor CPU averagingReuse helpers in recycler and manager computations
Reset
upflag each iteration, fixing stale stateDiagram Walkthrough
File Walkthrough
flow_threads.rs
Unify recycler and manager window computation logicsrc/flow_threads.rs
get_up_windowsfunction unifying the duplicatedwindow-scanning loops from recycler and manager computations,
parameterized by
thresholdandaboveget_window_cpu_average_vectorhelper for per-window CPU usageaveraging
get_recycler_countand manager count logic to consume thenew helpers
upflag at each loop iteration fixing stale state acrosswindows; fixed misplaced brace and added trailing newline