Async/Promise/Coroutine/Thread utilities for PocketMine-MP (virion-ready).
- PMMP API:
5.0.0 - PHP:
8.1 - 8.4
composer require reinfyteam/libvapm-pmmp- Download from Poggit: https://poggit.pmmp.io/ci/ReinfyTeam/LibVapmPMMP
- Place the virion in your project virions folder.
Initialize once in your plugin:
use pocketmine\plugin\PluginBase;
use vennv\vapm\VapmPMMP;
final class Main extends PluginBase{
protected function onEnable() : void{
VapmPMMP::init($this);
}
}VapmPMMP::init() registers the repeating event-loop tick task.
Calling it more than once (or with a different plugin instance) is guarded and will emit a warning.
use vennv\vapm\VapmPMMP;
use vennv\vapm\io\Io;
use vennv\vapm\ct\Ct;
use vennv\vapm\Promise;
use vennv\vapm\System;$job = Io::async(function () : string {
return "done";
});
$result = Io::await($job); // "done"Io::setTimeout(function () : void {
// run once after delay
}, 50);
Io::setInterval(function () : void {
// run repeatedly
}, 20);
Io::delay(100)->then(function () : void {
// delayed promise flow
});use Generator;
Ct::c(function () : Generator {
yield from Ct::cDelay(10);
// coroutine work
});
Ct::cBlock(function () : Generator {
yield from Ct::cDelay(5);
// blocking coroutine run
});$all = Promise::all([
Io::async(fn() => 1),
Io::async(fn() => 2),
]);
$values = Io::await($all); // [1, 2]Also available: Promise::allSettled(), Promise::any(), Promise::race().
System::fetch("https://example.com")->then(function ($response) : void {
// InternetRequestResult
});
System::read("/path/to/file.txt")->then(function (string $content) : void {
// file contents
});<<<<<<< HEAD
Io::delay(100)->then(function () : void {
// do primary operation
})->finally(function () : void {
// cleanup
});$task = System::setInterval(function () : void {
// heartbeat
}, 20);
System::setTimeout(function () use ($task) : void {
System::clearInterval($task);
}, 200);$result = Io::await(Promise::all([
Io::async(fn() => "A"),
Io::async(fn() => "B"),
]));System::fetch("https://example.com", [
"method" => "GET",
"timeout" => 5,
])->then(function ($response) : void {
// InternetRequestResult
});- Promise queue de-duplicates enqueues by Promise ID.
- Scheduler fairness is backlog-aware across Promise, coroutine, microtask, and macrotask queues.
- For large producers, tune chunking with
Settings::setWorkDrainChunkSize()andSettings::setWorkerProducerChunkSize(). - For low-end hosts, cap per-tick work with
Settings::setEventLoopLimits(),Settings::setMacroTaskLimits(), andSettings::setCoroutineLimits().
use vennv\vapm\EventLoop;
use vennv\vapm\Settings;
Settings::setSchedulerDebug(true);
Settings::setDebugLogIntervalTicks(20);
Settings::setHealthWarnBacklogThreshold(10000);
Settings::setHealthWarnDropThreshold(100);
$snapshot = EventLoop::getMetricsSnapshot();
// queueDepth, coroutineBacklog, microTaskBacklog, macroTaskBacklog, drops, processed counters...Static analysis gates:
composer analyse-src
composer analyse-schedulerVapmPMMP::init()is designed for API 5 tick scheduling (scheduleRepeatingTask(..., 1)).- In PMMP-managed mode, system-level tick/shutdown hooks are not auto-registered; PMMP scheduler drives the loop.
- In non-PMMP contexts, runtime hooks are attempted; if unavailable, LibVapmPMMP emits warnings and expects manual loop runs.
Compatibility check script:
composer compat-api5Run deterministic stress workloads:
composer benchmark-queue
composer benchmark-mixedFor before/after comparisons:
# before
git checkout <baseline-tag-or-commit>
composer benchmark-compare
# after
git checkout <your-branch>
composer benchmark-compareCapture both JSON outputs and compare:
metrics.totalBacklog,metrics.queueDepth,metrics.processed*metrics.droppedReturns,metrics.droppedDuplicateQueue
For optimization roadmap and upcoming improvements, see WATCHLIST.md.
- Keep long operations async/coroutine-based.
- Prefer batching and composition (
Promise::all, channels, await groups) over deep nested callbacks. - For optimization roadmap and upcoming improvements, see
WATCHLIST.md.
a01e0333b855038f1e6535c0724a400d2f919db9