Skip to content

Commit 04f7e26

Browse files
authored
Notebook query elapsed time (#644)
1 parent 4fe6b1f commit 04f7e26

File tree

6 files changed

+41
-15
lines changed

6 files changed

+41
-15
lines changed

pgml-dashboard/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod guards;
1919
pub mod models;
2020
mod responses;
2121
mod templates;
22+
mod utils;
2223

2324
use guards::Cluster;
2425
use responses::{BadRequest, ResponseOk};
@@ -558,6 +559,7 @@ pub async fn uploaded_index(cluster: Cluster, table_name: &str) -> ResponseOk {
558559
let sql = templates::Sql::new(
559560
cluster.pool(),
560561
&format!("SELECT * FROM {} LIMIT 10", table_name),
562+
true,
561563
)
562564
.await
563565
.unwrap();

pgml-dashboard/src/models.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -296,18 +296,19 @@ impl Cell {
296296
pub async fn render(&mut self, pool: &PgPool) -> anyhow::Result<()> {
297297
let cell_type: CellType = self.cell_type.into();
298298

299-
let rendering = match cell_type {
299+
let (rendering, execution_time) = match cell_type {
300300
CellType::Sql => {
301-
let queries = self.contents.split(";");
301+
let queries: Vec<&str> = self.contents.split(';').filter(|q| !q.trim().is_empty()).collect();
302302
let mut rendering = String::new();
303+
let mut total_execution_duration = std::time::Duration::default();
304+
let render_individual_execution_duration = queries.len() > 1;
303305

304306
for query in queries {
305-
if query.trim().is_empty() {
306-
continue;
307-
}
308-
309-
let result = match templates::Sql::new(pool, query).await {
310-
Ok(sql) => sql.render_once()?,
307+
let result = match templates::Sql::new(pool, query, render_individual_execution_duration).await {
308+
Ok(sql) => {
309+
total_execution_duration += sql.execution_duration;
310+
sql.render_once()?
311+
},
311312
Err(err) => templates::SqlError {
312313
error: format!("{:?}", err),
313314
}
@@ -317,7 +318,12 @@ impl Cell {
317318
rendering.push_str(&result);
318319
}
319320

320-
rendering
321+
let execution_time = PgInterval{
322+
months: 0,
323+
days: 0,
324+
microseconds: total_execution_duration.as_micros().try_into().unwrap_or(0)
325+
};
326+
(rendering, Some(execution_time))
321327
}
322328

323329
CellType::Markdown => {
@@ -335,21 +341,23 @@ impl Cell {
335341
front_matter_delimiter: None,
336342
};
337343

338-
format!(
344+
(format!(
339345
"<div class=\"markdown-body\">{}</div>",
340346
markdown_to_html(&self.contents, &options)
341-
)
347+
), None)
342348
}
343349
};
344350

345351
sqlx::query!(
346-
"UPDATE pgml.notebook_cells SET rendering = $1 WHERE id = $2",
352+
"UPDATE pgml.notebook_cells SET rendering = $1, execution_time = $2 WHERE id = $3",
347353
rendering,
354+
execution_time,
348355
self.id
349356
)
350357
.execute(pool)
351358
.await?;
352359

360+
self.execution_time = execution_time;
353361
self.rendering = Some(rendering);
354362

355363
Ok(())

pgml-dashboard/src/templates.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,12 @@ pub struct Undo {
5555
pub struct Sql {
5656
pub columns: Vec<String>,
5757
pub rows: Vec<Vec<String>>,
58+
pub execution_duration: std::time::Duration,
59+
pub render_execution_duration: bool,
5860
}
5961

6062
impl Sql {
61-
pub async fn new(pool: &PgPool, query: &str) -> anyhow::Result<Sql> {
63+
pub async fn new(pool: &PgPool, query: &str, render_execution_duration: bool) -> anyhow::Result<Sql> {
6264
let prepared_stmt = pool.prepare(query).await?;
6365
let cols = prepared_stmt.columns();
6466

@@ -67,7 +69,9 @@ impl Sql {
6769

6870
cols.iter().for_each(|c| columns.push(c.name().to_string()));
6971

72+
let now = std::time::Instant::now();
7073
let result = prepared_stmt.query().fetch_all(pool).await?;
74+
let execution_duration = now.elapsed();
7175

7276
for row in result.iter() {
7377
let mut values = Vec::new();
@@ -199,7 +203,7 @@ impl Sql {
199203
rows.push(values);
200204
}
201205

202-
Ok(Sql { columns, rows })
206+
Ok(Sql { columns, rows, execution_duration, render_execution_duration })
203207
}
204208
}
205209

pgml-dashboard/src/utils.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pub fn format_microseconds(microseconds: f64) -> String {
2+
if microseconds >= 1000000. {
3+
format!("{}s", microseconds / 1000000.)
4+
} else if microseconds >= 1000. {
5+
format!("{}ms", microseconds / 1000.)
6+
} else {
7+
format!("{}μs", microseconds)
8+
}
9+
}

pgml-dashboard/templates/cell.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<div class="notebook-duration">
7676
<div class="markdown-body">
7777
<div class="flex flex-row-reverse">
78-
<code>TODO</code>
78+
<code>Time: <%= crate::utils::format_microseconds(cell.execution_time.unwrap().microseconds as f64) %></code>
7979
</div>
8080
</div>
8181
</div>

pgml-dashboard/templates/sql.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<% } %>
2525
</tbody>
2626
</table>
27+
<% if render_execution_duration { %>
28+
<code>Time: <%= crate::utils::format_microseconds(execution_duration.as_micros() as f64) %></code>
29+
<% } %>
2730
</div>
2831

2932
<% } %>

0 commit comments

Comments
 (0)