Skip to content

Commit

Permalink
feat(console): nicer poll time layout in details view (console-rs#58)
Browse files Browse the repository at this point in the history
This branch slightly improves the layout of the poll time stats in the
task details view. Now, instead of doing a 50/50 horizontal split that
requires us to break the percentiles into two columns, we do an
asymmetrical horizontal split, and make the poll time area two lines
longer. This allows us to fit the percentiles in a single column, and
lets us draw a slightly bigger histogram (hopefully making it a little
nicer to read).

This also simplifies the code a little, since we can remove the code
for splitting the poll time histogram area into two columns.

Before:
![image](https://user-images.githubusercontent.com/2796466/124795284-b71e1f80-df04-11eb-87f4-6bb4e5b93518.png)

After:
![image](https://user-images.githubusercontent.com/2796466/124795123-96ee6080-df04-11eb-839c-c1cd5be8a329.png)
  • Loading branch information
hawkw authored Jul 7, 2021
1 parent 94e7834 commit 35d675f
Showing 1 changed file with 33 additions and 60 deletions.
93 changes: 33 additions & 60 deletions console/src/view/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl TaskView {
[
layout::Constraint::Length(1),
layout::Constraint::Length(6),
layout::Constraint::Length(7),
layout::Constraint::Length(9),
layout::Constraint::Percentage(60),
]
.as_ref(),
Expand All @@ -80,29 +80,18 @@ impl TaskView {
.direction(layout::Direction::Horizontal)
.constraints(
[
layout::Constraint::Percentage(50),
layout::Constraint::Percentage(50),
// 24 chars is long enough for the title "Poll Times Percentiles"
layout::Constraint::Max(24),
layout::Constraint::Min(50),
]
.as_ref(),
)
.split(chunks[2]);

let percentiles_columns = Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
layout::Constraint::Percentage(50),
layout::Constraint::Percentage(50),
]
.as_ref(),
)
.split(histogram_area[0].inner(&layout::Margin {
horizontal: 1,
vertical: 1,
}));
let percentiles_area = histogram_area[0];
let sparkline_area = histogram_area[1];

let fields_area = chunks[3];
let sparkline_area = histogram_area[1];

let controls = Spans::from(vec![
Span::raw("controls: "),
Expand Down Expand Up @@ -191,21 +180,18 @@ impl TaskView {
let task_widget = Paragraph::new(metrics).block(block_for("Task"));
let wakers_widget = Paragraph::new(vec![wakers, wakeups]).block(block_for("Waker"));
let fields_widget = Paragraph::new(fields).block(block_for("Fields"));

let percentiles_widget = block_for("Poll Times Percentiles");
let (percentiles_1, percentiles_2) = details
.map(|d| d.make_percentiles_widgets(5))
.unwrap_or_default();
let percentiles_widget_1 = Paragraph::new(percentiles_1);
let percentiles_widget_2 = Paragraph::new(percentiles_2);
let percentiles_widget = Paragraph::new(
details
.map(Details::make_percentiles_widget)
.unwrap_or_default(),
)
.block(block_for("Poll Times Percentiles"));

frame.render_widget(Block::default().title(controls), controls_area);
frame.render_widget(task_widget, stats_area[0]);
frame.render_widget(wakers_widget, stats_area[1]);
frame.render_widget(fields_widget, fields_area);
frame.render_widget(percentiles_widget, histogram_area[0]);
frame.render_widget(percentiles_widget_1, percentiles_columns[0]);
frame.render_widget(percentiles_widget_2, percentiles_columns[1]);
frame.render_widget(percentiles_widget, percentiles_area);
frame.render_widget(histogram_sparkline, sparkline_area);
}
}
Expand Down Expand Up @@ -255,39 +241,26 @@ impl Details {
.unwrap_or_default()
}

/// Get the important percentile values from the histogram and make two paragraphs listing them
fn make_percentiles_widgets(&self, column_height: usize) -> (Text<'static>, Text<'static>) {
let percentiles_iter = self
.poll_times_histogram()
.map(|histogram| {
[10f64, 25f64, 50f64, 75f64, 90f64, 95f64, 99f64]
.iter()
.map(move |i| (*i, histogram.value_at_percentile(*i)))
/// Get the important percentile values from the histogram
fn make_percentiles_widget(&self) -> Text<'static> {
let mut text = Text::default();
let histogram = self.poll_times_histogram();
let percentiles = histogram.iter().flat_map(|histogram| {
let pairs = [10f64, 25f64, 50f64, 75f64, 90f64, 95f64, 99f64]
.iter()
.map(move |i| (*i, histogram.value_at_percentile(*i)));
pairs.map(|pair| {
Spans::from(vec![
bold(format!("p{:>2}: ", pair.0)),
Span::from(format!(
"{:.prec$?}",
Duration::from_nanos(pair.1),
prec = DUR_PRECISION,
)),
])
})
.map(|pairs| {
pairs.map(|pair| {
Spans::from(vec![
bold(format!("p{:>2}: ", pair.0)),
Span::from(format!(
"{:.prec$?}",
Duration::from_nanos(pair.1),
prec = DUR_PRECISION,
)),
])
})
});

let mut percentiles_1 = Text::default();
let mut percentiles_2 = Text::default();
if let Some(mut percentiles_iter) = percentiles_iter {
percentiles_1.extend(
percentiles_iter
.by_ref()
.take(column_height)
.map(Spans::from),
);
percentiles_2.extend(percentiles_iter.map(Spans::from));
}
(percentiles_1, percentiles_2)
});
text.extend(percentiles);
text
}
}

0 comments on commit 35d675f

Please sign in to comment.