承接 initphp/fiber-loops 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

initphp/fiber-loops

Composer 安装命令:

composer require initphp/fiber-loops

包简介

A minimal cooperative task scheduler (event loop) for PHP, built on native fibers.

README 文档

README

CI License: MIT PHP Version

A minimal cooperative task scheduler for PHP, built on native fibers. Run several tasks on a single thread, hand control back and forth at points you choose, and wait for sub-tasks to finish — in a few dozen lines of dependency-free code.

php-fiber

What it is (and is not)

FiberLoops is a tiny scheduler. You queue tasks with defer() and drive them with run(). Each task is a fiber; the loop advances the tasks round-robin, running each one until it cooperatively yields (next() / sleep()) or returns.

Scheduling is cooperative, not preemptive: nothing interrupts a task. A task keeps the CPU until it yields or finishes, so long-running tasks must call next() periodically to let their siblings make progress. There is no I/O reactor, no stream/timer polling, no threads — it is a scheduling primitive you can build those things on top of, not a full async runtime like ReactPHP or Amp.

Requirements

  • PHP 8.1+ (fibers are a core language feature since 8.1 — no extension needed)

Installation

composer require initphp/fiber-loops

Quick start

require_once 'vendor/autoload.php';

use InitPHP\FiberLoops\Loop;

$loop = new Loop();

$loop->defer(function () use ($loop) {
    foreach (['a', 'b', 'c'] as $step) {
        echo "task-1: $step\n";
        $loop->next();              // yield: let other tasks run
    }
});

$loop->defer(function () use ($loop) {
    foreach (['x', 'y', 'z'] as $step) {
        echo "task-2: $step\n";
        $loop->next();
    }
});

$loop->run();                       // drive every task to completion
task-1: a
task-2: x
task-1: b
task-2: y
task-1: c
task-2: z

The two tasks interleave because each one yields with next() after every step. Remove the next() calls and the first task would run to completion before the second one started.

The API

Loop implements InitPHP\FiberLoops\LoopInterface. Depend on the interface when you want to substitute or mock the scheduler.

Method Description
defer(callable|Fiber $task): void Queue a task. A callable is wrapped in a fiber. Safe to call during run().
run(): void Run every queued task to completion (blocks until the queue is empty).
next(mixed $value = null): mixed Yield from the current task back to the scheduler. Must run inside a fiber.
sleep(int|float $seconds): void Cooperatively pause the current task. Must run inside a fiber.
await(callable|Fiber $task): mixed Run a task to completion and return its value, yielding while it works.

defer() and run()

defer() queues work; run() executes it. A task added during run() (from inside another task) is picked up on the next scheduling pass, so tasks can spawn more tasks.

next()

next() is the yield point. Calling it suspends the current task and lets the scheduler advance the others; the task resumes where it left off on the next pass. It must be called from within a fiber (i.e. inside a deferred or awaited task) — calling it from the main script throws a LoopException:

$loop->next(); // LoopException: Loop::next() must be called from within a fiber...

The bundled scheduler resumes tasks without a value, so next() returns null under run() and await(). The $value argument is reserved for custom drivers and is ignored here.

sleep()

sleep() pauses the current task for at least the given number of seconds while letting sibling tasks keep running:

$loop = new Loop();

$loop->defer(function () use ($loop) {
    $loop->sleep(0.2);              // yields repeatedly for ~200ms
    foreach (range(0, 5) as $value) {
        echo $value . PHP_EOL;
    }
});

$loop->defer(function () use ($loop) {
    foreach (range(6, 9) as $value) {
        echo $value . PHP_EOL;
    }
});

$loop->run();
6
7
8
9
0
1
2
3
4
5

The second task finishes first because the first one is sleeping. sleep() is a busy-wait that yields on every iteration: siblings progress, but the loop does not idle the CPU. sleep(0) (or any non-positive value) returns immediately without yielding. See docs/caveats.md for the implications.

await()

await() runs a task to completion and returns its value. From the main script it drives the task synchronously:

$loop = new Loop();

$user = $loop->await(function () use ($loop) {
    $loop->next();                  // may yield while doing work
    return ['id' => 42, 'name' => 'Ada'];
});

echo "user: {$user['id']} / {$user['name']}\n";   // user: 42 / Ada

Called from inside a task, await() yields to the scheduler while the awaited sub-task works, so other tasks keep running in the meantime:

$loop = new Loop();

$loop->defer(function () use ($loop) {
    echo "worker: awaiting a sub-task\n";
    $sum = $loop->await(function () use ($loop) {
        $total = 0;
        foreach (range(1, 3) as $n) {
            $total += $n;
            $loop->next();
        }
        return $total;
    });
    echo "worker: sub-task returned $sum\n";
});

$loop->defer(function () use ($loop) {
    foreach (['tick', 'tick', 'tick'] as $t) {
        echo "heartbeat: $t\n";
        $loop->next();
    }
});

$loop->run();
worker: awaiting a sub-task
heartbeat: tick
heartbeat: tick
heartbeat: tick
worker: sub-task returned 6

await() accepts a callable or a Fiber, started or not.

Error handling

next() and sleep() must be called from within a fiber. Doing otherwise throws InitPHP\FiberLoops\Exception\LoopException (a RuntimeException) with an actionable message, instead of PHP's bare FiberError.

Documentation

Full guides live in docs/:

Guide What it covers
Getting started Install, your first two tasks, how the loop runs them.
Concepts The scheduling model: fibers, the round-robin queue, cooperative yielding.
API reference Every method, its signature, behaviour and edge cases.
await & concurrency Awaiting sub-tasks from the main context and from inside a task.
Caveats & gotchas Busy-wait sleep(), in-fiber preconditions, non-preemptive scheduling.

Testing

composer install
composer test        # PHPUnit
composer ci          # cs-check + phpstan + tests

Contributing

Contributions are welcome. Please read the org-wide Contributing guide and the Security policy. Fork, branch, add tests for your change, and open a pull request.

Credits

License

Copyright © 2022 InitPHP — released under the MIT License.

initphp/fiber-loops 适用场景与选型建议

initphp/fiber-loops 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 11 次下载、GitHub Stars 达 6, 最近一次更新时间为 2022 年 07 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「event-loop」 「async」 「scheduler」 「loop」 「concurrency」 「coroutine」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 initphp/fiber-loops 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 initphp/fiber-loops 我们能提供哪些服务?
定制开发 / 二次开发

基于 initphp/fiber-loops 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 11
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 6
  • 点击次数: 27
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 6
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-07-12