mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add server-cli bench command for profiling that automates loading a certain area, running for a specific time, and then exiting.
This commit is contained in:
parent
6c57d17714
commit
aabf67a72a
@ -82,10 +82,23 @@ pub struct TuiApp {
|
||||
command: Message,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Parser)]
|
||||
pub struct BenchParams {
|
||||
/// View distance of the loaded area (in chunks)
|
||||
#[arg(long)]
|
||||
pub view_distance: u32,
|
||||
/// Duration to run after loading completes (in seconds).
|
||||
#[arg(long)]
|
||||
pub duration: u32,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
pub enum ArgvCommand {
|
||||
#[command(flatten)]
|
||||
Shared(SharedCommand),
|
||||
/// Load an area, run the server for some time, and then exit (useful for
|
||||
/// profiling).
|
||||
Bench(BenchParams),
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
|
@ -29,7 +29,7 @@ use server::{persistence::DatabaseSettings, settings::Protocol, Event, Input, Se
|
||||
use std::{
|
||||
io,
|
||||
sync::{atomic::AtomicBool, mpsc, Arc},
|
||||
time::Duration,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tracing::{info, trace};
|
||||
|
||||
@ -117,15 +117,16 @@ fn main() -> io::Result<()> {
|
||||
sql_log_mode,
|
||||
};
|
||||
|
||||
let mut bench = None;
|
||||
if let Some(command) = app.command {
|
||||
return match command {
|
||||
match command {
|
||||
ArgvCommand::Shared(SharedCommand::Admin { command }) => {
|
||||
let login_provider = server::login_provider::LoginProvider::new(
|
||||
server_settings.auth_server_address,
|
||||
runtime,
|
||||
);
|
||||
|
||||
match command {
|
||||
return match command {
|
||||
Admin::Add { username, role } => {
|
||||
// FIXME: Currently the UUID can get returned even if the file didn't
|
||||
// change, so this can't be relied on as an error
|
||||
@ -139,6 +140,7 @@ fn main() -> io::Result<()> {
|
||||
&mut editable_settings,
|
||||
&server_data_dir,
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
Admin::Remove { username } => {
|
||||
// FIXME: Currently the UUID can get returned even if the file didn't
|
||||
@ -152,9 +154,15 @@ fn main() -> io::Result<()> {
|
||||
&mut editable_settings,
|
||||
&server_data_dir,
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
},
|
||||
ArgvCommand::Bench(params) => {
|
||||
bench = Some(params);
|
||||
// If we are trying to benchmark, don't limit the server view distance.
|
||||
server_settings.max_view_distance = None;
|
||||
// TODO: add setting to adjust entity spawn density
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -207,12 +215,28 @@ fn main() -> io::Result<()> {
|
||||
|
||||
// Set up an fps clock
|
||||
let mut clock = Clock::new(Duration::from_secs_f64(1.0 / TPS as f64));
|
||||
// Wait for a tick so we don't start with a zero dt
|
||||
|
||||
if let Some(bench) = bench {
|
||||
#[cfg(feature = "worldgen")]
|
||||
server.create_centered_persister(bench.view_distance);
|
||||
}
|
||||
let mut bench_exit_time = None;
|
||||
|
||||
let mut tick_no = 0u64;
|
||||
loop {
|
||||
tick_no += 1;
|
||||
span!(guard, "work");
|
||||
if let Some(bench) = bench {
|
||||
if let Some(t) = bench_exit_time {
|
||||
if Instant::now() > t {
|
||||
break;
|
||||
}
|
||||
} else if tick_no != 0 && !server.chunks_pending() {
|
||||
println!("Chunk loading complete");
|
||||
bench_exit_time = Some(Instant::now() + Duration::from_secs(bench.duration.into()));
|
||||
}
|
||||
};
|
||||
|
||||
tick_no += 1;
|
||||
// Terminate the server if instructed to do so by the shutdown coordinator
|
||||
if shutdown_coordinator.check(&mut server, &settings) {
|
||||
break;
|
||||
|
@ -1442,6 +1442,15 @@ impl Server {
|
||||
.build();
|
||||
}
|
||||
|
||||
/// Used by benchmarking code.
|
||||
pub fn chunks_pending(&mut self) -> bool {
|
||||
self.state_mut()
|
||||
.mut_resource::<ChunkGenerator>()
|
||||
.pending_chunks()
|
||||
.next()
|
||||
.is_some()
|
||||
}
|
||||
|
||||
/// Sets the SQL log mode at runtime
|
||||
pub fn set_sql_log_mode(&mut self, sql_log_mode: SqlLogMode) {
|
||||
// Unwrap is safe here because we only perform a variable assignment with the
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
chunk_generator::ChunkGenerator,
|
||||
metrics::{EcsSystemMetrics, JobMetrics, PhysicsMetrics, TickMetrics},
|
||||
HwStats, Tick, TickStart,
|
||||
};
|
||||
@ -12,11 +13,12 @@ use std::time::Instant;
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Option<Entities<'a>>,
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, HwStats>,
|
||||
ReadExpect<'a, Tick>,
|
||||
ReadExpect<'a, TimeOfDay>,
|
||||
ReadExpect<'a, TickStart>,
|
||||
ReadExpect<'a, ChunkGenerator>,
|
||||
Option<Read<'a, TerrainGrid>>,
|
||||
Read<'a, SysMetrics>,
|
||||
Read<'a, common_ecs::PhysicsMetrics>,
|
||||
@ -39,6 +41,7 @@ impl<'a> System<'a> for Sys {
|
||||
tick,
|
||||
time_of_day,
|
||||
tick_start,
|
||||
chunk_generator,
|
||||
terrain,
|
||||
sys_metrics,
|
||||
phys_metrics,
|
||||
@ -89,7 +92,7 @@ impl<'a> System<'a> for Sys {
|
||||
// Report other info
|
||||
export_tick.time_of_day.set(time_of_day.0);
|
||||
if tick.0.rem_euclid(100) == 0 {
|
||||
if let Some(terrain) = terrain {
|
||||
if let Some(terrain) = terrain.as_ref() {
|
||||
let mut chonk_cnt = 0;
|
||||
let mut group_cnt = 0;
|
||||
let chunk_cnt = terrain.iter().fold(0, |a, (_, c)| {
|
||||
@ -102,11 +105,16 @@ impl<'a> System<'a> for Sys {
|
||||
export_tick.chunk_groups_count.set(group_cnt as i64);
|
||||
}
|
||||
|
||||
if let Some(entities) = entities {
|
||||
let entity_count = entities.join().count();
|
||||
export_tick.entity_count.set(entity_count as i64);
|
||||
common_base::plot!("entity count", entity_count as f64);
|
||||
}
|
||||
let entity_count = entities.join().count();
|
||||
export_tick.entity_count.set(entity_count as i64);
|
||||
}
|
||||
common_base::plot!("entity count", entities.join().count() as f64);
|
||||
common_base::plot!(
|
||||
"pending chunks",
|
||||
chunk_generator.pending_chunks().count() as f64
|
||||
);
|
||||
if let Some(terrain) = terrain.as_ref() {
|
||||
common_base::plot!("chunk count", terrain.iter().count() as f64);
|
||||
}
|
||||
|
||||
//detailed physics metrics
|
||||
|
Loading…
Reference in New Issue
Block a user