First look at splitting up AsyncPool and ServerScheduler

This commit contains quite a few breaking changes with respect to how AsyncTasks are handled. This is necessary to allow separation of the ServerScheduler and the AsyncPool, because in the future the ServerScheduler may be removed and instead there will be isolated per-plugin sync-task schedulers - but we cannot have every plugin with its own worker pool for memory usage reasons if nothing else.

The following things have changed:
- ServerScheduler: scheduleAsyncTask(), scheduleAsyncTaskToWorker(), getAsyncTaskPoolSize(), increaseAsyncTaskPoolSize() and similar methods have all been removed. Additionally the static \$WORKERS field has been removed.
- Server: added API method getAsyncPool(). This grants you direct access to the server's AsyncPool. Calls to getScheduler()->scheduleAsyncTask() and scheduleAsyncTaskToWorker() should be replaced with getAsyncPool()->submitTask() and submitTaskToWorker() respectively.
This commit is contained in:
Dylan K. Taylor
2018-05-30 12:20:10 +01:00
parent 7fce48d38c
commit d03f36ebee
10 changed files with 54 additions and 91 deletions

View File

@ -87,6 +87,7 @@ use pocketmine\plugin\PluginLoadOrder;
use pocketmine\plugin\PluginManager;
use pocketmine\plugin\ScriptPluginLoader;
use pocketmine\resourcepacks\ResourcePackManager;
use pocketmine\scheduler\AsyncPool;
use pocketmine\scheduler\FileWriteTask;
use pocketmine\scheduler\SendUsageTask;
use pocketmine\scheduler\ServerScheduler;
@ -150,6 +151,8 @@ class Server{
/** @var ServerScheduler */
private $scheduler = null;
/** @var AsyncPool */
private $asyncPool;
/**
* Counts the ticks since the server start
@ -657,6 +660,10 @@ class Server{
return $this->scheduler;
}
public function getAsyncPool() : AsyncPool{
return $this->asyncPool;
}
/**
* @return int
*/
@ -824,7 +831,7 @@ class Server{
$nbt = new BigEndianNBTStream();
try{
if($async){
$this->getScheduler()->scheduleAsyncTask(new FileWriteTask($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())));
$this->asyncPool->submitTask(new FileWriteTask($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())));
}else{
file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData()));
}
@ -1518,8 +1525,10 @@ class Server{
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET]));
$this->scheduler = new ServerScheduler();
if(($poolSize = $this->getProperty("settings.async-workers", "auto")) === "auto"){
$poolSize = ServerScheduler::$WORKERS;
$poolSize = 2;
$processors = Utils::getCoreCount() - 2;
if($processors > 0){
@ -1529,7 +1538,7 @@ class Server{
$poolSize = (int) $poolSize;
}
ServerScheduler::$WORKERS = $poolSize;
$this->asyncPool = new AsyncPool($this, $poolSize);
if($this->getProperty("network.batch-threshold", 256) >= 0){
Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256);
@ -1551,7 +1560,6 @@ class Server{
$this->doTitleTick = ((bool) $this->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes();
$this->scheduler = new ServerScheduler();
if($this->getConfigBool("enable-rcon", false)){
try{
@ -1903,7 +1911,7 @@ class Server{
if(!$forceSync and !$immediate and $this->networkCompressionAsync){
$task = new CompressBatchedTask($pk, $targets);
$this->getScheduler()->scheduleAsyncTask($task);
$this->asyncPool->submitTask($task);
}else{
$this->broadcastPacketsCallback($pk, $targets, $immediate);
}
@ -2068,8 +2076,12 @@ class Server{
HandlerList::unregisterAll();
if($this->scheduler instanceof ServerScheduler){
$this->getLogger()->debug("Shutting down task scheduler");
$this->scheduler->shutdown();
$this->getLogger()->debug("Stopping all tasks");
$this->scheduler->cancelAllTasks();
}
if($this->asyncPool instanceof AsyncPool){
$this->getLogger()->debug("Shutting down async task worker pool");
$this->asyncPool->shutdown();
}
if($this->properties !== null and $this->properties->hasChanged()){
@ -2427,7 +2439,7 @@ class Server{
public function sendUsage($type = SendUsageTask::TYPE_STATUS){
if((bool) $this->getProperty("anonymous-statistics.enabled", true)){
$this->scheduler->scheduleAsyncTask(new SendUsageTask($this, $type, $this->uniquePlayers));
$this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers));
}
$this->uniquePlayers = [];
}
@ -2525,6 +2537,10 @@ class Server{
$this->scheduler->mainThreadHeartbeat($this->tickCounter);
Timings::$schedulerTimer->stopTiming();
Timings::$schedulerAsyncTimer->startTiming();
$this->asyncPool->collectTasks();
Timings::$schedulerAsyncTimer->stopTiming();
$this->checkTickUpdates($this->tickCounter, $tickTime);
foreach($this->players as $player){