Ask servers for runs and perform them
This commit is contained in:
parent
eaca373a6a
commit
b7c0443005
3 changed files with 164 additions and 32 deletions
|
|
@ -1,12 +1,77 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Notify;
|
||||
use tracing::error;
|
||||
|
||||
use crate::shared::{Run, Source};
|
||||
use crate::{
|
||||
shared::{BenchMethod, FinishedRun, Measurement, Run, Source},
|
||||
somehow,
|
||||
};
|
||||
|
||||
struct Finished {
|
||||
exit_code: i32,
|
||||
measurements: HashMap<String, Measurement>,
|
||||
}
|
||||
|
||||
// TODO Make fields private
|
||||
#[derive(Clone)]
|
||||
pub struct RunInProgress {
|
||||
pub server_name: String,
|
||||
pub run: Run,
|
||||
pub output: Arc<Mutex<Vec<(Source, String)>>>,
|
||||
pub abort: mpsc::UnboundedSender<()>,
|
||||
pub abort: Arc<Notify>,
|
||||
}
|
||||
|
||||
impl RunInProgress {
|
||||
pub fn new(server_name: String, run: Run) -> Self {
|
||||
Self {
|
||||
server_name,
|
||||
run,
|
||||
output: Arc::new(Mutex::new(vec![])),
|
||||
abort: Arc::new(Notify::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log_stdout(&self, line: String) {
|
||||
self.output.lock().unwrap().push((Source::Stdout, line));
|
||||
}
|
||||
|
||||
pub fn log_stderr(&self, line: String) {
|
||||
self.output.lock().unwrap().push((Source::Stderr, line));
|
||||
}
|
||||
|
||||
pub async fn perform(&self) -> Option<FinishedRun> {
|
||||
// TODO Remove type annotations
|
||||
// TODO Handle aborts
|
||||
let result: somehow::Result<_> = match &self.run.bench_method {
|
||||
BenchMethod::Internal => todo!(),
|
||||
BenchMethod::Repo { hash } => todo!(),
|
||||
};
|
||||
|
||||
let finished = match result {
|
||||
Ok(outcome) => outcome,
|
||||
Err(e) => {
|
||||
error!("Error during run:\n{e:?}");
|
||||
self.log_stderr("Internal error:".to_string());
|
||||
self.log_stderr(format!("{e:?}"));
|
||||
Some(Finished {
|
||||
exit_code: -1,
|
||||
measurements: HashMap::new(),
|
||||
})
|
||||
}
|
||||
}?;
|
||||
|
||||
let mut output = vec![];
|
||||
std::mem::swap(&mut output, &mut *self.output.lock().unwrap());
|
||||
|
||||
Some(FinishedRun {
|
||||
run: self.run.clone(),
|
||||
exit_code: finished.exit_code,
|
||||
output,
|
||||
measurements: finished.measurements,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,17 +45,35 @@ impl Server {
|
|||
// TODO Limit status requests to one in flight at a time (per server)
|
||||
pub async fn post_status(
|
||||
&self,
|
||||
status: WorkerStatus,
|
||||
request_work: bool,
|
||||
submit_work: Option<FinishedRun>,
|
||||
request_run: bool,
|
||||
submit_run: Option<FinishedRun>,
|
||||
) -> somehow::Result<ServerResponse> {
|
||||
let url = format!("{}api/worker/status", self.server_config.url);
|
||||
|
||||
let status = match &*self.current_run.lock().unwrap() {
|
||||
Some(run) if run.server_name == self.name => WorkerStatus::Working(UnfinishedRun {
|
||||
run: run.run.clone(),
|
||||
last_output: run
|
||||
.output
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.rev()
|
||||
.take(SCROLLBACK)
|
||||
.rev()
|
||||
.cloned()
|
||||
.collect(),
|
||||
}),
|
||||
Some(_) => WorkerStatus::Busy,
|
||||
None => WorkerStatus::Idle,
|
||||
};
|
||||
|
||||
let request = WorkerRequest {
|
||||
info: None,
|
||||
secret: self.secret.clone(),
|
||||
status,
|
||||
request_run: request_work,
|
||||
submit_run: submit_work,
|
||||
request_run,
|
||||
submit_run,
|
||||
};
|
||||
|
||||
let response = self
|
||||
|
|
@ -107,25 +125,7 @@ impl Server {
|
|||
debug!("Pinging server");
|
||||
let guard = self.status_lock.lock().await;
|
||||
|
||||
let status = match &*self.current_run.lock().unwrap() {
|
||||
Some(run) if run.server_name == self.name => WorkerStatus::Working(UnfinishedRun {
|
||||
run: run.run.clone(),
|
||||
last_output: run
|
||||
.output
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.rev()
|
||||
.take(SCROLLBACK)
|
||||
.rev()
|
||||
.cloned()
|
||||
.collect(),
|
||||
}),
|
||||
Some(_) => WorkerStatus::Busy,
|
||||
None => WorkerStatus::Idle,
|
||||
};
|
||||
|
||||
let response = self.post_status(status, false, None).await?;
|
||||
let response = self.post_status(false, None).await?;
|
||||
|
||||
// TODO Signal that run should be aborted
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue