update RunMatch helper to allow for remote bots

This commit is contained in:
Ilion Beyst 2022-06-10 21:49:32 +02:00
parent 5ee66c9c9b
commit a376698073
5 changed files with 50 additions and 22 deletions

View file

@ -25,7 +25,7 @@ pub struct NewMatchPlayer {
/// player id within the match /// player id within the match
pub player_id: i32, pub player_id: i32,
/// id of the bot behind this player /// id of the bot behind this player
pub code_bundle_id: i32, pub code_bundle_id: Option<i32>,
} }
#[derive(Queryable, Identifiable)] #[derive(Queryable, Identifiable)]
@ -48,7 +48,7 @@ pub struct MatchPlayer {
} }
pub struct MatchPlayerData { pub struct MatchPlayerData {
pub code_bundle_id: i32, pub code_bundle_id: Option<i32>,
} }
pub fn create_match( pub fn create_match(

View file

@ -16,32 +16,54 @@ use crate::{
const PYTHON_IMAGE: &str = "python:3.10-slim-buster"; const PYTHON_IMAGE: &str = "python:3.10-slim-buster";
pub struct RunMatch<'a> { pub struct RunMatch {
log_file_name: String, log_file_name: String,
player_code_bundles: Vec<&'a db::bots::CodeBundle>, players: Vec<MatchPlayer>,
match_id: Option<i32>, match_id: Option<i32>,
} }
impl<'a> RunMatch<'a> { pub struct MatchPlayer {
pub fn from_players(player_code_bundles: Vec<&'a db::bots::CodeBundle>) -> Self { bot_spec: Box<dyn BotSpec>,
// meta that will be passed on to database
code_bundle_id: Option<i32>,
}
impl MatchPlayer {
pub fn from_code_bundle(code_bundle: &db::bots::CodeBundle) -> Self {
MatchPlayer {
bot_spec: code_bundle_to_botspec(code_bundle),
code_bundle_id: Some(code_bundle.id),
}
}
pub fn from_bot_spec(bot_spec: Box<dyn BotSpec>) -> Self {
MatchPlayer {
bot_spec,
code_bundle_id: None,
}
}
}
impl RunMatch {
pub fn from_players(players: Vec<MatchPlayer>) -> Self {
let log_file_name = format!("{}.log", gen_alphanumeric(16)); let log_file_name = format!("{}.log", gen_alphanumeric(16));
RunMatch { RunMatch {
log_file_name, log_file_name,
player_code_bundles, players,
match_id: None, match_id: None,
} }
} }
pub fn runner_config(&self) -> runner::MatchConfig { pub fn into_runner_config(self) -> runner::MatchConfig {
runner::MatchConfig { runner::MatchConfig {
map_path: PathBuf::from(MAPS_DIR).join("hex.json"), map_path: PathBuf::from(MAPS_DIR).join("hex.json"),
map_name: "hex".to_string(), map_name: "hex".to_string(),
log_path: PathBuf::from(MATCHES_DIR).join(&self.log_file_name), log_path: PathBuf::from(MATCHES_DIR).join(&self.log_file_name),
players: self players: self
.player_code_bundles .players
.iter() .into_iter()
.map(|b| runner::MatchPlayer { .map(|player| runner::MatchPlayer {
bot_spec: code_bundle_to_botspec(b), bot_spec: player.bot_spec,
}) })
.collect(), .collect(),
} }
@ -56,10 +78,10 @@ impl<'a> RunMatch<'a> {
log_path: &self.log_file_name, log_path: &self.log_file_name,
}; };
let new_match_players = self let new_match_players = self
.player_code_bundles .players
.iter() .iter()
.map(|b| db::matches::MatchPlayerData { .map(|p| db::matches::MatchPlayerData {
code_bundle_id: b.id, code_bundle_id: p.code_bundle_id,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -70,7 +92,7 @@ impl<'a> RunMatch<'a> {
pub fn spawn(self, pool: ConnectionPool) -> JoinHandle<MatchOutcome> { pub fn spawn(self, pool: ConnectionPool) -> JoinHandle<MatchOutcome> {
let match_id = self.match_id.expect("match must be saved before running"); let match_id = self.match_id.expect("match must be saved before running");
let runner_config = self.runner_config(); let runner_config = self.into_runner_config();
tokio::spawn(run_match_task(pool, runner_config, match_id)) tokio::spawn(run_match_task(pool, runner_config, match_id))
} }
} }

View file

@ -1,7 +1,7 @@
use crate::{db::bots::Bot, DbPool}; use crate::{db::bots::Bot, DbPool};
use crate::db; use crate::db;
use crate::modules::matches::RunMatch; use crate::modules::matches::{MatchPlayer, RunMatch};
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use std::time::Duration; use std::time::Duration;
use tokio; use tokio;
@ -43,9 +43,12 @@ async fn play_ranking_match(selected_bots: Vec<Bot>, db_pool: DbPool) {
code_bundles.push(code_bundle); code_bundles.push(code_bundle);
} }
let code_bundle_refs = code_bundles.iter().map(|b| b).collect::<Vec<_>>(); let players = code_bundles
.iter()
.map(MatchPlayer::from_code_bundle)
.collect::<Vec<_>>();
let mut run_match = RunMatch::from_players(code_bundle_refs); let mut run_match = RunMatch::from_players(players);
run_match run_match
.store_in_database(&db_conn) .store_in_database(&db_conn)
.expect("could not store match in db"); .expect("could not store match in db");

View file

@ -1,7 +1,7 @@
use crate::db; use crate::db;
use crate::db::matches::{FullMatchData, FullMatchPlayerData}; use crate::db::matches::{FullMatchData, FullMatchPlayerData};
use crate::modules::bots::save_code_bundle; use crate::modules::bots::save_code_bundle;
use crate::modules::matches::RunMatch; use crate::modules::matches::{MatchPlayer, RunMatch};
use crate::ConnectionPool; use crate::ConnectionPool;
use axum::extract::Extension; use axum::extract::Extension;
use axum::Json; use axum::Json;
@ -46,7 +46,10 @@ pub async fn submit_bot(
// TODO: can we recover from this? // TODO: can we recover from this?
.expect("could not save bot code"); .expect("could not save bot code");
let mut run_match = RunMatch::from_players(vec![&player_code_bundle, &opponent_code_bundle]); let mut run_match = RunMatch::from_players(vec![
MatchPlayer::from_code_bundle(&player_code_bundle),
MatchPlayer::from_code_bundle(&opponent_code_bundle),
]);
let match_data = run_match let match_data = run_match
.store_in_database(&conn) .store_in_database(&conn)
.expect("failed to save match"); .expect("failed to save match");

View file

@ -61,7 +61,7 @@ pub async fn play_match(
}); });
bot_ids.push(matches::MatchPlayerData { bot_ids.push(matches::MatchPlayerData {
code_bundle_id: code_bundle.id, code_bundle_id: Some(code_bundle.id),
}); });
} }