vennv / vapm-pmmp
2.5.6
2024-09-02 05:40 UTC
Requires
- php: >=8.2
- php-64bit: *
- composer-runtime-api: ^2.0
- pocketmine/pocketmine-mp: ^5.17.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-10-02 05:50:28 UTC
README
- 这是为 PocketMine-PMMP 设计的 Virion Async/Promise/Coroutine/Thread/GreenThread
Composer
composer require vennv/vapm-pmmp
如何设置?
- 在此处官方下载 Phar:点击此处
- 将它们下载并放入您的 Virion 文件夹中。如果您不明白 Virion 是什么,请点击此处
- 要实现和使用方法,您必须首先在插件 onEnable 函数的顶部使用此库的方法
- 示例
protected function onEnable() : void { VapmPMMP::init($this); }
- 什么是 VapmPMMP::init($this) ?
/** * @param PluginBase $plugin * * This method is called by VapmPMMP::init(), it will run event loop. */ public static function init(PluginBase $plugin) : void;
- 最后,这里是您可以使用的方法指南:点击此处
- 这是插件示例
- VFormOOPAPI
- SimplifyLibasynql
- VSharedData
- VJesusBucket
- VBasket
- VOreSpawner
LibVapmPMMP 与 Await-Generator 的比较
- 为什么处理大型系统? Vapm 使用基于 tick 的执行的任务调度器,而 Await-Generator 使用队列并在作用域内即时执行。比较这两种异步模型,一种使用队列存储并在特定作用域内即时执行,另一种将任务保存到任务调度器以进行 tick 执行,应基于以下因素
- 性能和灵活性
- 在作用域内即时排队和执行: 由于任务在队列中出现时立即执行,因此此模型通常在处理方面更快。然而,如果同时出现太多任务,可能会导致过载,因为它们都在同一时间进行处理。
- 基于 tick 的任务调度器: 使用任务调度器可以通过在 tick 中执行任务来控制任务的处理速度。这有助于避免过载并允许更流畅的系统资源分配。但是,如果 tick 设置了较长的间隔,则执行可能会变慢。
- 资源控制
- 排队和即时执行: 如果需要立即处理大量任务,则可能会消耗更多资源,从而导致资源耗尽或系统延迟增加的风险。
- 任务调度器: 通过在每个 tick 中仅执行有限数量的任务来帮助您更好地管理和控制资源,从而减轻系统压力。
- 实时响应
- 排队和即时执行: 如果需要实时反馈,则任务即时处理更好。
- 任务调度器: 由于任务必须等待下一个 tick 才能被处理,因此可能不适合需要即时响应的应用程序。
- 复杂性和维护
- 排队和即时执行: 通常部署起来更简单,但如果系统高度复杂,则难以管理。
- 任务调度器: 虽然更复杂,但长期来看提供了更多灵活性和易于维护。
- 用例
- 排队和即时执行: 适用于需要立即处理且不涉及太多并发任务的应用程序。
- 任务调度器: 适用于更复杂的系统,有时需要控制任务的处理,以确保稳定的性能。
- 性能和灵活性
- 那么,您是否有办法将 Vapm 作为等待生成器使用? 您可以通过运行
CoroutineGen::runBlocking()
或AwaitGroup
等方法来实现,这些方法在 Vapm 中或更多其他地方可用。 - 在任务调度器上处理此类异步任务是否可以? 这是完全可以的,因为任务调度器只能处理最多 20 个异步任务和 +1 个计划中的 CoroutineGens。(请注意,这里的处理意味着它将只处理每个任务一次,如果未完成,则跳过并在下一次处理!)
- 为什么可以这样做? 当您知道它们在您认为任务非常繁重的地方等待时,这确实非常稳定!例如:点击 如您所见,我在那一刻停下来等待任务完成,而 Tick-Scheduler 会重复并再次处理。这使得在另一个 tick 中可以同时处理许多其他任务。
- 等待生成器问题: Await-Generator 存在一个问题,即如果我创建一个承诺并要求它在声明后立即运行,而不等待,就像有一个用于数十亿个数字的 for 循环一样,如果我等待并在下面运行承诺,它将告诉我我在同步?我注意到库的 Await 处理类中有一个队列,然而,假设如果没有承诺被触发,需要满足的承诺是在它们被处理时?它们何时是实时的?如果我想处理 10 亿个任务并立即在完成后完成一些参数来做下一件事怎么办?请注意,这是 10 亿。
- Await-Generator
$channel = new Channel; Await::f2c(function() use ($channel) { for ($i = 0; $i < 5000000; $i++) { yield from $channel->sendAndWait($i); } });
- Vapm
/** * @throws Throwable */ public function loadWorlds(): Channel { $channel = new Channel(); CoroutineGen::runNonBlocking(function () use (&$channel): Generator { $i = 0; foreach (scandir($this->plugin->getServer()->getDataPath() . "worlds") as $world) { if ($world === "." || $world === "..") continue; if ($this->plugin->getManager()->isIslandNether($world)) { $i++; yield from $channel->sendGen($i); $this->applyIslandNether($world); } elseif ($this->plugin->getManager()->isIslandEnd($world)) { $i++; yield from $channel->sendGen($i); $this->applyIslandEnd($world); } else { $this->applyIslandOverworld($world); } } return $i; }); return $channel; } // Process with Task by PMMP // Load worlds if ( self::$doneLoadWorlds === null && (microtime(true) - self::$lastTimeLoadWorlds) >= 5.0 ) { self::$lastTimeLoadWorlds = microtime(true); self::$doneLoadWorlds = $this->plugin->getWorldManager()->loadWorlds(); } elseif (self::$doneLoadWorlds !== null) { CoroutineGen::runNonBlocking(function (): Generator { yield from self::$doneLoadWorlds->receiveGen(fn() => null); self::$doneLoadWorlds = null; }); } // Completely waits and processes each slow incoming content that Channel sends without over-load the server when too many things are sent and received at once.
问题出现了,为什么我必须等待这么长时间来处理这种大的分歧,而不是异步快速和缓慢地通过 ticks 来处理?
- 速度测试: 代码 根据固有方法,Await-Generator 仍然想要像往常一样等待和处理,而不使用任务调度器。