From e69bd14f1d64b0d8b2438a40a069d3647c1edd73 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 12 Jul 2022 20:54:00 +0200 Subject: [PATCH] refactor: delay BotSpec construction in RunMatch --- planetwars-server/src/db/bots.rs | 2 +- planetwars-server/src/modules/bot_api.rs | 15 ++++-- planetwars-server/src/modules/matches.rs | 60 +++++++++--------------- planetwars-server/src/modules/ranking.rs | 5 +- planetwars-server/src/routes/demo.rs | 10 +++- 5 files changed, 45 insertions(+), 47 deletions(-) diff --git a/planetwars-server/src/db/bots.rs b/planetwars-server/src/db/bots.rs index 1654f43..a112a9a 100644 --- a/planetwars-server/src/db/bots.rs +++ b/planetwars-server/src/db/bots.rs @@ -51,7 +51,7 @@ pub struct NewBotVersion<'a> { pub container_digest: Option<&'a str>, } -#[derive(Queryable, Serialize, Deserialize, Debug)] +#[derive(Queryable, Serialize, Deserialize, Clone, Debug)] pub struct BotVersion { pub id: i32, pub bot_id: Option, diff --git a/planetwars-server/src/modules/bot_api.rs b/planetwars-server/src/modules/bot_api.rs index 732aa21..962b33d 100644 --- a/planetwars-server/src/modules/bot_api.rs +++ b/planetwars-server/src/modules/bot_api.rs @@ -102,10 +102,10 @@ impl pb::bot_api_service_server::BotApiService for BotApiServer { let match_request = req.get_ref(); - let opponent = db::bots::find_bot_by_name(&match_request.opponent_name, &conn) + let opponent_bot = db::bots::find_bot_by_name(&match_request.opponent_name, &conn) .map_err(|_| Status::not_found("opponent not found"))?; - let opponent_code_bundle = db::bots::active_bot_version(opponent.id, &conn) - .map_err(|_| Status::not_found("opponent has no code"))?; + let opponent_bot_version = db::bots::active_bot_version(opponent_bot.id, &conn) + .map_err(|_| Status::not_found("no opponent version found"))?; let player_key = gen_alphanumeric(32); @@ -114,8 +114,13 @@ impl pb::bot_api_service_server::BotApiService for BotApiServer { router: self.router.clone(), }); let mut run_match = RunMatch::from_players(vec![ - MatchPlayer::from_bot_spec(remote_bot_spec), - MatchPlayer::from_bot_version(&opponent, &opponent_code_bundle), + MatchPlayer::BotSpec { + spec: remote_bot_spec, + }, + MatchPlayer::BotVersion { + bot: Some(opponent_bot), + version: opponent_bot_version, + }, ]); let created_match = run_match .store_in_database(&conn) diff --git a/planetwars-server/src/modules/matches.rs b/planetwars-server/src/modules/matches.rs index 03be5db..0496db7 100644 --- a/planetwars-server/src/modules/matches.rs +++ b/planetwars-server/src/modules/matches.rs @@ -22,39 +22,14 @@ pub struct RunMatch { match_id: Option, } -pub struct MatchPlayer { - bot_spec: Box, - // metadata that will be passed on to database - code_bundle_id: Option, -} - -impl MatchPlayer { - pub fn from_bot_version(bot: &db::bots::Bot, version: &db::bots::BotVersion) -> Self { - MatchPlayer { - bot_spec: bot_version_to_botspec(bot, version), - code_bundle_id: Some(version.id), - } - } - - /// Construct a MatchPlayer from a BotVersion that certainly contains a code bundle path. - /// Will panic when this is not the case. - pub fn from_code_bundle_version(version: &db::bots::BotVersion) -> Self { - let code_bundle_path = version - .code_bundle_path - .as_ref() - .expect("no code_bundle_path found"); - MatchPlayer { - bot_spec: python_docker_bot_spec(code_bundle_path), - code_bundle_id: Some(version.id), - } - } - - pub fn from_bot_spec(bot_spec: Box) -> Self { - MatchPlayer { - bot_spec, - code_bundle_id: None, - } - } +pub enum MatchPlayer { + BotVersion { + bot: Option, + version: db::bots::BotVersion, + }, + BotSpec { + spec: Box, + }, } impl RunMatch { @@ -76,7 +51,12 @@ impl RunMatch { .players .into_iter() .map(|player| runner::MatchPlayer { - bot_spec: player.bot_spec, + bot_spec: match player { + MatchPlayer::BotVersion { bot, version } => { + bot_version_to_botspec(bot.as_ref(), &version) + } + MatchPlayer::BotSpec { spec } => spec, + }, }) .collect(), } @@ -94,11 +74,14 @@ impl RunMatch { .players .iter() .map(|p| db::matches::MatchPlayerData { - code_bundle_id: p.code_bundle_id, + code_bundle_id: match p { + MatchPlayer::BotVersion { version, .. } => Some(version.id), + MatchPlayer::BotSpec { .. } => None, + }, }) .collect::>(); - let match_data = db::matches::create_match(&new_match_data, &new_match_players, &db_conn)?; + 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) } @@ -111,12 +94,12 @@ impl RunMatch { } pub fn bot_version_to_botspec( - bot: &db::bots::Bot, + bot: Option<&db::bots::Bot>, bot_version: &db::bots::BotVersion, ) -> Box { if let Some(code_bundle_path) = &bot_version.code_bundle_path { python_docker_bot_spec(code_bundle_path) - } else if let Some(container_digest) = &bot_version.container_digest { + } else if let (Some(container_digest), Some(bot)) = (&bot_version.container_digest, bot) { // TODO: put this in config let registry_url = "localhost:9001"; Box::new(DockerBotSpec { @@ -126,6 +109,7 @@ pub fn bot_version_to_botspec( working_dir: None, }) } else { + // TODO: ideally this would not be possible panic!("bad bot version") } } diff --git a/planetwars-server/src/modules/ranking.rs b/planetwars-server/src/modules/ranking.rs index 3182ce2..7147b98 100644 --- a/planetwars-server/src/modules/ranking.rs +++ b/planetwars-server/src/modules/ranking.rs @@ -41,7 +41,10 @@ async fn play_ranking_match(selected_bots: Vec, db_pool: DbPool) { for bot in &selected_bots { let version = db::bots::active_bot_version(bot.id, &db_conn) .expect("could not get active bot version"); - let player = MatchPlayer::from_bot_version(bot, &version); + let player = MatchPlayer::BotVersion { + bot: Some(bot.clone()), + version, + }; players.push(player); } diff --git a/planetwars-server/src/routes/demo.rs b/planetwars-server/src/routes/demo.rs index 1a6ae9a..f9929f7 100644 --- a/planetwars-server/src/routes/demo.rs +++ b/planetwars-server/src/routes/demo.rs @@ -47,8 +47,14 @@ pub async fn submit_bot( .expect("could not save bot code"); let mut run_match = RunMatch::from_players(vec![ - MatchPlayer::from_code_bundle_version(&player_bot_version), - MatchPlayer::from_bot_version(&opponent_bot, &opponent_bot_version), + MatchPlayer::BotVersion { + bot: None, + version: player_bot_version.clone(), + }, + MatchPlayer::BotVersion { + bot: Some(opponent_bot.clone()), + version: opponent_bot_version.clone(), + }, ]); let match_data = run_match .store_in_database(&conn)