Test and fix scheduler cycle budgets
This commit is contained in:
@@ -37,7 +37,8 @@ public final class SimulationScheduler {
|
||||
}
|
||||
|
||||
public boolean shouldRunSimulationCycle() {
|
||||
return minecraftTickCounter % config.getSimulationIntervalTicks() == 0;
|
||||
return minecraftTickCounter > 0
|
||||
&& minecraftTickCounter % config.getSimulationIntervalTicks() == 0;
|
||||
}
|
||||
|
||||
public void queueRegion(RegionUpdateJob job) {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.livingworld.core.simulation;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.livingworld.config.SimulationConfig;
|
||||
import com.livingworld.regions.RegionCoordinate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SchedulerBudgetTest {
|
||||
|
||||
@Test
|
||||
void oneCycleReturnsAtMostConfiguredRegionBudget() {
|
||||
SimulationScheduler scheduler = scheduler(50, 100);
|
||||
for (int index = 0; index < 500; index++) {
|
||||
scheduler.queueRegion(job(index, index % 10));
|
||||
}
|
||||
|
||||
List<RegionUpdateJob> jobs = scheduler.pollJobsForCycle();
|
||||
|
||||
assertEquals(50, jobs.size());
|
||||
assertEquals(450, scheduler.getQueuedJobCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void higherPriorityJobsAreReturnedFirst() {
|
||||
SimulationScheduler scheduler = scheduler(3, 100);
|
||||
scheduler.queueRegion(job(0, 1));
|
||||
scheduler.queueRegion(job(1, 20));
|
||||
scheduler.queueRegion(job(2, 5));
|
||||
scheduler.queueRegion(job(3, 10));
|
||||
|
||||
assertEquals(
|
||||
List.of(20, 10, 5),
|
||||
scheduler.pollJobsForCycle().stream()
|
||||
.map(RegionUpdateJob::priority)
|
||||
.toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void jobsOutsideCurrentBudgetRemainQueued() {
|
||||
SimulationScheduler scheduler = scheduler(2, 100);
|
||||
scheduler.queueRegion(job(0, 3));
|
||||
scheduler.queueRegion(job(1, 2));
|
||||
scheduler.queueRegion(job(2, 1));
|
||||
|
||||
scheduler.pollJobsForCycle();
|
||||
|
||||
assertEquals(1, scheduler.getQueuedJobCount());
|
||||
assertEquals(1, scheduler.pollJobsForCycle().getFirst().priority());
|
||||
}
|
||||
|
||||
@Test
|
||||
void simulationIntervalStartsAfterTheConfiguredNumberOfTicks() {
|
||||
SimulationScheduler scheduler = scheduler(50, 3);
|
||||
|
||||
assertFalse(scheduler.shouldRunSimulationCycle());
|
||||
scheduler.onMinecraftTick();
|
||||
assertFalse(scheduler.shouldRunSimulationCycle());
|
||||
scheduler.onMinecraftTick();
|
||||
assertFalse(scheduler.shouldRunSimulationCycle());
|
||||
scheduler.onMinecraftTick();
|
||||
assertTrue(scheduler.shouldRunSimulationCycle());
|
||||
scheduler.onMinecraftTick();
|
||||
assertFalse(scheduler.shouldRunSimulationCycle());
|
||||
}
|
||||
|
||||
private static SimulationScheduler scheduler(int maxRegionsPerCycle, int intervalTicks) {
|
||||
SimulationConfig config = new SimulationConfig();
|
||||
config.setMaxRegionsPerCycle(maxRegionsPerCycle);
|
||||
config.setSimulationIntervalTicks(intervalTicks);
|
||||
return new SimulationScheduler(config);
|
||||
}
|
||||
|
||||
private static RegionUpdateJob job(int coordinateX, int priority) {
|
||||
return new RegionUpdateJob(
|
||||
new RegionCoordinate("minecraft:overworld", coordinateX, 0),
|
||||
priority,
|
||||
0,
|
||||
Set.of(),
|
||||
UpdateReason.NORMAL_ROLLING_UPDATE);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user