perf(server): budget per-tick chunk delivery
This commit is contained in:
parent
d33fb518fa
commit
e6c55cfd6a
|
|
@ -18,6 +18,10 @@ pub const SERVER_MAX_RADIUS: u16 = 12;
|
||||||
/// Worldgen version stamped on delivered chunk diffs. A single version exists today; this becomes the chunk's stored version once worldgen versioning lands.
|
/// Worldgen version stamped on delivered chunk diffs. A single version exists today; this becomes the chunk's stored version once worldgen versioning lands.
|
||||||
const WORLDGEN_VERSION: u32 = 0;
|
const WORLDGEN_VERSION: u32 = 0;
|
||||||
|
|
||||||
|
/// Upper bound on chunks encoded and sent to one client per tick.
|
||||||
|
// TODO: replace the fixed count with a time budget once per-chunk cost varies with LOD.
|
||||||
|
const MAX_DELIVERIES_PER_TICK: usize = 32;
|
||||||
|
|
||||||
/// The load and drop lists produced by diffing a client's previous desired set against a new one.
|
/// The load and drop lists produced by diffing a client's previous desired set against a new one.
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct DesiredDiff {
|
pub struct DesiredDiff {
|
||||||
|
|
@ -94,7 +98,7 @@ impl ClientStream {
|
||||||
|
|
||||||
/// Delivers every desired-but-undelivered chunk that has become resident in `world`.
|
/// Delivers every desired-but-undelivered chunk that has become resident in `world`.
|
||||||
///
|
///
|
||||||
/// Each chunk is encoded as a [`ChunkData`] diff against `baseline` (an all-air chunk), making the payload self-contained. Positions still pending in the worker pool are skipped and retried on a later call. Returns the number of chunks delivered.
|
/// Each chunk is encoded as a [`ChunkData`] diff against `baseline` (an all-air chunk), making the payload self-contained. Positions still pending in the worker pool are skipped and retried on a later call, as are positions beyond [`MAX_DELIVERIES_PER_TICK`]. Returns the number of chunks delivered.
|
||||||
pub fn flush(&mut self, world: &ServerWorld, baseline: &Chunk) -> usize {
|
pub fn flush(&mut self, world: &ServerWorld, baseline: &Chunk) -> usize {
|
||||||
// Collected first to avoid borrowing `self.desired` while mutating `self.sent`.
|
// Collected first to avoid borrowing `self.desired` while mutating `self.sent`.
|
||||||
let ready: Vec<ChunkPos> = self
|
let ready: Vec<ChunkPos> = self
|
||||||
|
|
@ -106,6 +110,11 @@ impl ClientStream {
|
||||||
|
|
||||||
let mut delivered = 0;
|
let mut delivered = 0;
|
||||||
for pos in ready {
|
for pos in ready {
|
||||||
|
// The budget counts chunks actually encoded, so ticks where most of the desired set is still in flight are not charged for work they did not do.
|
||||||
|
if delivered >= MAX_DELIVERIES_PER_TICK {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let Some(chunk) = world.chunk(pos) else {
|
let Some(chunk) = world.chunk(pos) else {
|
||||||
// Not resident yet; a later flush retries once the worker pool returns it.
|
// Not resident yet; a later flush retries once the worker pool returns it.
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -225,10 +225,8 @@ fn run_simulation(world: &mut World, network: &NetworkServer) -> ! {
|
||||||
ServerEvent::ChunkSubscribe { id, request } => {
|
ServerEvent::ChunkSubscribe { id, request } => {
|
||||||
if let Some(client) = clients.get_mut(&id) {
|
if let Some(client) = clients.get_mut(&id) {
|
||||||
let (added, drops) = client.resubscribe(request.center, request.radius);
|
let (added, drops) = client.resubscribe(request.center, request.radius);
|
||||||
info!(
|
// Fires on every chunk boundary the client crosses, so it sits below the connect and disconnect events rather than beside them.
|
||||||
id,
|
debug!(id, added, drops, "client resubscribed");
|
||||||
added, drops, "client {id}: +{added} chunks, -{drops} drops"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
warn!(id, "chunk subscribe from unknown session");
|
warn!(id, "chunk subscribe from unknown session");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue