refactor: unify match save and spawn
This commit is contained in:
parent
e69bd14f1d
commit
668409e76d
4 changed files with 32 additions and 30 deletions
|
@ -122,10 +122,10 @@ impl pb::bot_api_service_server::BotApiService for BotApiServer {
|
|||
version: opponent_bot_version,
|
||||
},
|
||||
]);
|
||||
let created_match = run_match
|
||||
.store_in_database(&conn)
|
||||
.expect("failed to save match");
|
||||
run_match.spawn(self.conn_pool.clone());
|
||||
let (created_match, _) = run_match
|
||||
.run(self.conn_pool.clone())
|
||||
.await
|
||||
.expect("failed to create match");
|
||||
|
||||
Ok(Response::new(pb::CreatedMatch {
|
||||
match_id: created_match.base.id,
|
||||
|
|
|
@ -19,7 +19,6 @@ const PYTHON_IMAGE: &str = "python:3.10-slim-buster";
|
|||
pub struct RunMatch {
|
||||
log_file_name: String,
|
||||
players: Vec<MatchPlayer>,
|
||||
match_id: Option<i32>,
|
||||
}
|
||||
|
||||
pub enum MatchPlayer {
|
||||
|
@ -38,7 +37,6 @@ impl RunMatch {
|
|||
RunMatch {
|
||||
log_file_name,
|
||||
players,
|
||||
match_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,10 +60,24 @@ impl RunMatch {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn store_in_database(&mut self, db_conn: &PgConnection) -> QueryResult<MatchData> {
|
||||
// don't store the same match twice
|
||||
assert!(self.match_id.is_none());
|
||||
pub async fn run(
|
||||
self,
|
||||
conn_pool: ConnectionPool,
|
||||
) -> QueryResult<(MatchData, JoinHandle<MatchOutcome>)> {
|
||||
let match_data = {
|
||||
// TODO: it would be nice to get an already-open connection here when possible.
|
||||
// Maybe we need an additional abstraction, bundling a connection and connection pool?
|
||||
let db_conn = conn_pool.get().await.expect("could not get a connection");
|
||||
self.store_in_database(&db_conn)?
|
||||
};
|
||||
|
||||
let runner_config = self.into_runner_config();
|
||||
let handle = tokio::spawn(run_match_task(conn_pool, runner_config, match_data.base.id));
|
||||
|
||||
Ok((match_data, handle))
|
||||
}
|
||||
|
||||
fn store_in_database(&self, db_conn: &PgConnection) -> QueryResult<MatchData> {
|
||||
let new_match_data = db::matches::NewMatch {
|
||||
state: db::matches::MatchState::Playing,
|
||||
log_path: &self.log_file_name,
|
||||
|
@ -81,15 +93,7 @@ impl RunMatch {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let match_data = db::matches::create_match(&new_match_data, &new_match_players, db_conn)?;
|
||||
self.match_id = Some(match_data.base.id);
|
||||
Ok(match_data)
|
||||
}
|
||||
|
||||
pub fn spawn(self, pool: ConnectionPool) -> JoinHandle<MatchOutcome> {
|
||||
let match_id = self.match_id.expect("match must be saved before running");
|
||||
let runner_config = self.into_runner_config();
|
||||
tokio::spawn(run_match_task(pool, runner_config, match_id))
|
||||
db::matches::create_match(&new_match_data, &new_match_players, db_conn)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,14 +48,12 @@ async fn play_ranking_match(selected_bots: Vec<Bot>, db_pool: DbPool) {
|
|||
players.push(player);
|
||||
}
|
||||
|
||||
let mut run_match = RunMatch::from_players(players);
|
||||
run_match
|
||||
.store_in_database(&db_conn)
|
||||
.expect("could not store match in db");
|
||||
run_match
|
||||
.spawn(db_pool.clone())
|
||||
let (_, handle) = RunMatch::from_players(players)
|
||||
.run(db_pool.clone())
|
||||
.await
|
||||
.expect("running match failed");
|
||||
.expect("failed to run match");
|
||||
// wait for match to complete, so that only one ranking match can be running
|
||||
let _outcome = handle.await;
|
||||
}
|
||||
|
||||
fn recalculate_ratings(db_conn: &PgConnection) -> QueryResult<()> {
|
||||
|
|
|
@ -46,7 +46,7 @@ pub async fn submit_bot(
|
|||
// TODO: can we recover from this?
|
||||
.expect("could not save bot code");
|
||||
|
||||
let mut run_match = RunMatch::from_players(vec![
|
||||
let run_match = RunMatch::from_players(vec![
|
||||
MatchPlayer::BotVersion {
|
||||
bot: None,
|
||||
version: player_bot_version.clone(),
|
||||
|
@ -56,10 +56,10 @@ pub async fn submit_bot(
|
|||
version: opponent_bot_version.clone(),
|
||||
},
|
||||
]);
|
||||
let match_data = run_match
|
||||
.store_in_database(&conn)
|
||||
.expect("failed to save match");
|
||||
run_match.spawn(pool.clone());
|
||||
let (match_data, _) = run_match
|
||||
.run(pool.clone())
|
||||
.await
|
||||
.expect("failed to run match");
|
||||
|
||||
// TODO: avoid clones
|
||||
let full_match_data = FullMatchData {
|
||||
|
|
Loading…
Reference in a new issue