Add /runner/:name endpoint

This commit is contained in:
Joscha 2023-08-10 21:26:57 +02:00
parent b5bdd49d9c
commit 0253d2d90b
6 changed files with 79 additions and 26 deletions

View file

@ -5,6 +5,7 @@ use time::OffsetDateTime;
use crate::{config::Config, shared::RunnerStatus}; use crate::{config::Config, shared::RunnerStatus};
#[derive(Clone)]
pub struct RunnerInfo { pub struct RunnerInfo {
pub secret: String, pub secret: String,
pub last_seen: OffsetDateTime, pub last_seen: OffsetDateTime,
@ -81,4 +82,8 @@ impl Runners {
.find(|hash| !covered.contains(hash)) .find(|hash| !covered.contains(hash))
.map(|hash| hash as &str) .map(|hash| hash as &str)
} }
pub fn get(&self, name: &str) -> Option<RunnerInfo> {
self.runners.get(name).cloned()
}
} }

View file

@ -2,6 +2,7 @@ mod api;
mod commit; mod commit;
mod index; mod index;
mod queue; mod queue;
mod runner;
mod r#static; mod r#static;
use axum::{routing::get, Router}; use axum::{routing::get, Router};
@ -44,6 +45,7 @@ pub async fn run(server: Server) -> somehow::Result<()> {
let app = Router::new() let app = Router::new()
.route("/", get(index::get)) .route("/", get(index::get))
.route("/commit/:hash", get(commit::get)) .route("/commit/:hash", get(commit::get))
.route("/runner/:name", get(runner::get))
.route("/queue/", get(queue::get)) .route("/queue/", get(queue::get))
.route("/queue/table", get(queue::get_table)) .route("/queue/table", get(queue::get_table))
.merge(api::router(&server)) .merge(api::router(&server))

42
src/server/web/runner.rs Normal file
View file

@ -0,0 +1,42 @@
use std::sync::{Arc, Mutex};
use askama::Template;
use axum::{
extract::{Path, State},
http::StatusCode,
response::{IntoResponse, Response},
};
use crate::{
config::Config,
server::{runners::Runners, util},
somehow,
};
use super::{Base, Tab};
#[derive(Template)]
#[template(path = "runner.html")]
struct RunnerTemplate {
base: Base,
name: String,
last_seen: String,
// TODO Status
}
pub async fn get(
Path(name): Path<String>,
State(config): State<&'static Config>,
State(runners): State<Arc<Mutex<Runners>>>,
) -> somehow::Result<Response> {
let Some(info) = runners.lock().unwrap().get(&name) else {
return Ok(StatusCode::NOT_FOUND.into_response());
};
Ok(RunnerTemplate {
base: Base::new(config, Tab::Commit),
name,
last_seen: util::format_time(info.last_seen),
}
.into_response())
}

View file

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr}; use serde_repr::{Deserialize_repr, Serialize_repr};
use time::OffsetDateTime; use time::OffsetDateTime;
#[derive(Serialize_repr, Deserialize_repr)] #[derive(Clone, Serialize_repr, Deserialize_repr)]
#[repr(i8)] #[repr(i8)]
pub enum Direction { pub enum Direction {
LessIsBetter = -1, LessIsBetter = -1,
@ -14,7 +14,7 @@ pub enum Direction {
MoreIsBetter = 1, MoreIsBetter = 1,
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct Measurement { pub struct Measurement {
pub value: f64, pub value: f64,
pub stddev: Option<f64>, pub stddev: Option<f64>,
@ -22,7 +22,7 @@ pub struct Measurement {
pub direction: Option<i8>, pub direction: Option<i8>,
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum Line { pub enum Line {
@ -30,7 +30,7 @@ pub enum Line {
Stderr(String), Stderr(String),
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct FinishedRun { pub struct FinishedRun {
pub id: String, pub id: String,
pub start: OffsetDateTime, pub start: OffsetDateTime,
@ -40,7 +40,7 @@ pub struct FinishedRun {
pub measurements: HashMap<String, Measurement>, pub measurements: HashMap<String, Measurement>,
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum RunnerStatus { pub enum RunnerStatus {
@ -57,7 +57,7 @@ pub enum RunnerStatus {
}, },
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct RunnerRequest { pub struct RunnerRequest {
/// Additional free-form info about the runner. /// Additional free-form info about the runner.
/// ///
@ -80,7 +80,7 @@ pub struct RunnerRequest {
pub submit_work: Option<FinishedRun>, pub submit_work: Option<FinishedRun>,
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
#[serde(rename = "snake_case")] #[serde(rename = "snake_case")]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum BenchMethod { pub enum BenchMethod {
@ -90,7 +90,7 @@ pub enum BenchMethod {
BenchRepo { hash: String }, BenchRepo { hash: String },
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct Work { pub struct Work {
/// Hash of commit to benchmark. /// Hash of commit to benchmark.
pub hash: String, pub hash: String,

View file

@ -21,6 +21,12 @@ a:hover {
font-weight: bold; font-weight: bold;
} }
dl {
display: grid;
grid: auto-flow / min-content 1fr;
column-gap: 1ch;
}
dd { dd {
margin-left: 4ch; margin-left: 4ch;
} }
@ -116,34 +122,18 @@ nav a:hover {
font-weight: bold; font-weight: bold;
} }
.commit dl {
display: grid;
grid: auto-flow / min-content 1fr;
column-gap: 1ch;
}
.commit pre { .commit pre {
margin: 1em 0ch 1em 4ch; margin: 1em 0ch 1em 4ch;
white-space: pre-wrap; white-space: pre-wrap;
} }
/* Task */ /* Runner */
.task * { .runner .name {
margin: 0;
}
.task .id {
color: #380; color: #380;
font-weight: bold; font-weight: bold;
} }
.task dl {
display: grid;
grid: auto-flow / min-content 1fr;
column-gap: 1ch;
}
/* Queue */ /* Queue */
.queue td:nth-child(2), .queue td:nth-child(2),

14
templates/runner.html Normal file
View file

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block title %}{{ name }}{% endblock %}
{% block body %}
<h2>Runner</h2>
<div class="runner">
<span class="name">runner {{ name }}</span>
<dl>
<dt>Last seen:</dt>
<dd>{{ last_seen }}</dd>
</dl>
</div>
{% endblock %}