From c66a3a8b3e0340fc0fbb34757855f4b5e42069e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 May 2023 01:09:22 +0100 Subject: [PATCH] Update to Snooze 0.5.0 --- composer.json | 2 +- composer.lock | 19 +++++++-------- src/network/mcpe/raklib/RakLibInterface.php | 25 ++++++++++---------- src/network/mcpe/raklib/RakLibServer.php | 6 ++--- src/scheduler/AsyncPool.php | 26 ++++++++++----------- src/scheduler/AsyncWorker.php | 14 +++++++++-- 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/composer.json b/composer.json index fd47dca93..392cbd8c6 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "pocketmine/nbt": "^0.3.2", "pocketmine/raklib": "^0.15.0", "pocketmine/raklib-ipc": "^0.2.0", - "pocketmine/snooze": "dev-master", + "pocketmine/snooze": "^0.5.0", "ramsey/uuid": "^4.1", "symfony/filesystem": "^5.4" }, diff --git a/composer.lock b/composer.lock index a9d1e6d81..f1b31a9d7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "812a98ecf031488987b3216e785fee19", + "content-hash": "4bccf431b24bf685b0829ea44e54e806", "packages": [ { "name": "adhocore/json-comment", @@ -774,16 +774,16 @@ }, { "name": "pocketmine/snooze", - "version": "dev-master", + "version": "0.5.0", "source": { "type": "git", "url": "https://github.com/pmmp/Snooze.git", - "reference": "3207a201cbb10eebb4a96749678f7adef216bb71" + "reference": "a86d9ee60ce44755d166d3c7ba4b8b8be8360915" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Snooze/zipball/3207a201cbb10eebb4a96749678f7adef216bb71", - "reference": "3207a201cbb10eebb4a96749678f7adef216bb71", + "url": "https://api.github.com/repos/pmmp/Snooze/zipball/a86d9ee60ce44755d166d3c7ba4b8b8be8360915", + "reference": "a86d9ee60ce44755d166d3c7ba4b8b8be8360915", "shasum": "" }, "require": { @@ -795,7 +795,6 @@ "phpstan/phpstan": "1.10.3", "phpstan/phpstan-strict-rules": "^1.0" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -809,9 +808,9 @@ "description": "Thread notification management library for code using the pthreads extension", "support": { "issues": "https://github.com/pmmp/Snooze/issues", - "source": "https://github.com/pmmp/Snooze/tree/master" + "source": "https://github.com/pmmp/Snooze/tree/0.5.0" }, - "time": "2023-05-19T23:38:19+00:00" + "time": "2023-05-22T23:43:01+00:00" }, { "name": "ramsey/collection", @@ -3205,9 +3204,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pocketmine/snooze": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 68f02b649..93dff68a2 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -39,7 +39,6 @@ use pocketmine\network\NetworkInterfaceStartException; use pocketmine\network\PacketHandlingException; use pocketmine\player\GameMode; use pocketmine\Server; -use pocketmine\snooze\SleeperNotifier; use pocketmine\timings\Timings; use pocketmine\utils\Utils; use raklib\generic\DisconnectReason; @@ -79,7 +78,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ private RakLibToUserThreadMessageReceiver $eventReceiver; private UserToRakLibThreadMessageSender $interface; - private SleeperNotifier $sleeper; + private int $sleeperNotifierId; private PacketBroadcaster $packetBroadcaster; private EntityEventBroadcaster $entityEventBroadcaster; @@ -104,7 +103,15 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->rakServerId = mt_rand(0, PHP_INT_MAX); - $this->sleeper = new SleeperNotifier(); + $sleeperEntry = $this->server->getTickSleeper()->addNotifier(function() : void{ + Timings::$connection->startTiming(); + try{ + while($this->eventReceiver->handle($this)); + }finally{ + Timings::$connection->stopTiming(); + } + }); + $this->sleeperNotifierId = $sleeperEntry->getNotifierId(); /** @phpstan-var ThreadSafeArray $mainToThreadBuffer */ $mainToThreadBuffer = new ThreadSafeArray(); @@ -119,7 +126,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->rakServerId, $this->server->getConfigGroup()->getPropertyInt("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, - $this->sleeper + $sleeperEntry ); $this->eventReceiver = new RakLibToUserThreadMessageReceiver( new PthreadsChannelReader($threadToMainBuffer) @@ -130,14 +137,6 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function start() : void{ - $this->server->getTickSleeper()->addNotifier($this->sleeper, function() : void{ - Timings::$connection->startTiming(); - try{ - while($this->eventReceiver->handle($this)); - }finally{ - Timings::$connection->stopTiming(); - } - }); $this->server->getLogger()->debug("Waiting for RakLib to start..."); try{ $this->rakLib->startAndWait(); @@ -182,7 +181,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function shutdown() : void{ - $this->server->getTickSleeper()->removeNotifier($this->sleeper); + $this->server->getTickSleeper()->removeNotifier($this->sleeperNotifierId); $this->rakLib->quit(); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 5d4492f5f..a3f7c1609 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\raklib; use pmmp\thread\Thread as NativeThread; use pmmp\thread\ThreadSafeArray; -use pocketmine\snooze\SleeperNotifier; +use pocketmine\snooze\SleeperHandlerEntry; use pocketmine\thread\log\ThreadSafeLogger; use pocketmine\thread\NonThreadSafeValue; use pocketmine\thread\Thread; @@ -63,7 +63,7 @@ class RakLibServer extends Thread{ protected int $serverId, protected int $maxMtuSize, protected int $protocolVersion, - protected SleeperNotifier $mainThreadNotifier + protected SleeperHandlerEntry $sleeperEntry ){ $this->mainPath = \pocketmine\PATH; $this->address = new NonThreadSafeValue($address); @@ -133,7 +133,7 @@ class RakLibServer extends Thread{ $this->maxMtuSize, new SimpleProtocolAcceptor($this->protocolVersion), new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), - new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), + new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->sleeperEntry->createNotifier())), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 1ee726765..6a696fd1b 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -26,7 +26,6 @@ namespace pocketmine\scheduler; use pmmp\thread\Thread as NativeThread; use pmmp\thread\ThreadSafeArray; use pocketmine\snooze\SleeperHandler; -use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\log\ThreadSafeLogger; use pocketmine\thread\ThreadSafeClassLoader; use pocketmine\utils\Utils; @@ -52,8 +51,8 @@ class AsyncPool{ private array $taskQueues = []; /** - * @var AsyncWorker[] - * @phpstan-var array + * @var AsyncPoolWorkerEntry[] + * @phpstan-var array */ private array $workers = []; /** @@ -132,13 +131,12 @@ class AsyncPool{ */ private function getWorker(int $worker) : AsyncWorker{ if(!isset($this->workers[$worker])){ - $notifier = new SleeperNotifier(); - $this->workers[$worker] = new AsyncWorker($this->logger, $worker, $this->workerMemoryLimit, $notifier); - $this->eventLoop->addNotifier($notifier, function() use ($worker) : void{ + $sleeperEntry = $this->eventLoop->addNotifier(function() use ($worker) : void{ $this->collectTasksFromWorker($worker); }); - $this->workers[$worker]->setClassLoaders([$this->classLoader]); - $this->workers[$worker]->start(self::WORKER_START_OPTIONS); + $this->workers[$worker] = new AsyncPoolWorkerEntry(new AsyncWorker($this->logger, $worker, $this->workerMemoryLimit, $sleeperEntry), $sleeperEntry->getNotifierId()); + $this->workers[$worker]->worker->setClassLoaders([$this->classLoader]); + $this->workers[$worker]->worker->start(self::WORKER_START_OPTIONS); $this->taskQueues[$worker] = new \SplQueue(); @@ -147,7 +145,7 @@ class AsyncPool{ } } - return $this->workers[$worker]; + return $this->workers[$worker]->worker; } /** @@ -270,7 +268,7 @@ class AsyncPool{ break; //current task is still running, skip to next worker } } - $this->workers[$worker]->collect(); + $this->workers[$worker]->worker->collect(); return $more; } @@ -289,8 +287,8 @@ class AsyncPool{ $time = time(); foreach($this->taskQueues as $i => $queue){ if((!isset($this->workerLastUsed[$i]) || $this->workerLastUsed[$i] + 300 < $time) && $queue->isEmpty()){ - $this->workers[$i]->quit(); - $this->eventLoop->removeNotifier($this->workers[$i]->getNotifier()); + $this->workers[$i]->worker->quit(); + $this->eventLoop->removeNotifier($this->workers[$i]->sleeperNotifierId); unset($this->workers[$i], $this->taskQueues[$i], $this->workerLastUsed[$i]); $ret++; } @@ -308,8 +306,8 @@ class AsyncPool{ } foreach($this->workers as $worker){ - $worker->quit(); - $this->eventLoop->removeNotifier($worker->getNotifier()); + $worker->worker->quit(); + $this->eventLoop->removeNotifier($worker->sleeperNotifierId); } $this->workers = []; $this->taskQueues = []; diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index 89908ff31..517542495 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -24,9 +24,11 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pmmp\thread\Thread as NativeThread; +use pocketmine\snooze\SleeperHandlerEntry; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\log\ThreadSafeLogger; use pocketmine\thread\Worker; +use pocketmine\utils\AssumptionFailedError; use function gc_enable; use function ini_set; @@ -34,15 +36,21 @@ class AsyncWorker extends Worker{ /** @var mixed[] */ private static array $store = []; + private const TLS_KEY_NOTIFIER = self::class . "::notifier"; + public function __construct( private ThreadSafeLogger $logger, private int $id, private int $memoryLimit, - private SleeperNotifier $notifier + private SleeperHandlerEntry $sleeperEntry ){} public function getNotifier() : SleeperNotifier{ - return $this->notifier; + $notifier = $this->getFromThreadStore(self::TLS_KEY_NOTIFIER); + if(!$notifier instanceof SleeperNotifier){ + throw new AssumptionFailedError("SleeperNotifier not found in thread-local storage"); + } + return $notifier; } protected function onRun() : void{ @@ -57,6 +65,8 @@ class AsyncWorker extends Worker{ ini_set('memory_limit', '-1'); $this->logger->debug("No memory limit set"); } + + $this->saveToThreadStore(self::TLS_KEY_NOTIFIER, $this->sleeperEntry->createNotifier()); } public function getLogger() : ThreadSafeLogger{