From bacdb7bde551e058410e0de823f15a1ac868d56d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Dec 2020 15:44:17 +0000 Subject: [PATCH] Make sure generator gets preemptively registered when a worker restart is detected if a PopulationTask took place after the target worker was garbage collected, the population would fail and the chunks it used would be copied for nothing. This change marks workers as having unregistered generators when detecting that a worker that previously had a generator registered is restarted. --- src/world/World.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index fe6d4c2c2..0f403dc2d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -87,6 +87,7 @@ use pocketmine\world\sound\Sound; use pocketmine\world\utils\SubChunkExplorer; use function abs; use function array_fill_keys; +use function array_key_exists; use function array_map; use function array_merge; use function array_sum; @@ -405,6 +406,16 @@ class World implements ChunkManager{ } $this->timings = new WorldTimings($this); + + $this->workerPool->addWorkerStartHook($workerStartHook = function(int $workerId) : void{ + if(array_key_exists($workerId, $this->generatorRegisteredWorkers)){ + $this->logger->debug("Worker $workerId with previously registered generator restarted, flagging as unregistered"); + unset($this->generatorRegisteredWorkers[$workerId]); + } + }); + $this->addOnUnloadCallback(function() use ($workerStartHook) : void{ + $this->workerPool->removeWorkerStartHook($workerStartHook); + }); } public function getTickRateTime() : float{ @@ -412,8 +423,9 @@ class World implements ChunkManager{ } public function registerGeneratorToWorker(int $worker) : void{ - $this->generatorRegisteredWorkers[$worker] = true; + $this->logger->debug("Registering generator on worker $worker"); $this->workerPool->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); + $this->generatorRegisteredWorkers[$worker] = true; } public function unregisterGenerator() : void{