cloudtay / ripple

🚀 A modern, high-performance, native PHP coroutine engine.
https://github.com/cloudtay/ripple
MIT License
131 stars 7 forks source link

Laravel11项目,启动就报错了 #9

Closed leideqin closed 3 months ago

leideqin commented 3 months ago

Fatal error: Uncaught FiberError: Cannot suspend outside of a fiber in /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-core/src/Library/System/Process/Process.php:260 Stack trace:

0 /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-core/src/Library/System/Process/Process.php(260): Fiber::suspend()

1 [internal function]: Psc\Library\System\Process\Process->Psc\Library\System\Process{closure}(Object(Psc\Library\Net\Http\Server\HttpServer))

2 /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-core/src/Library/System/Process/Task.php(60): call_user_func(Object(Closure), Object(Psc\Library\Net\Http\Server\HttpServer))

3 /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-drive/src/Laravel/Guide.php(253): Psc\Library\System\Process\Task->run(Object(Psc\Library\Net\Http\Server\HttpServer))

4 /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-drive/src/Laravel/Guide.php(341): class@anonymous->addThread()

5 /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-drive/src/Laravel/Guide.php(367): class@anonymous->launch()

6 {main}

thrown in /home/leideqin/canteen/canteen-app/vendor/cclilshy/p-ripple-core/src/Library/System/Process/Process.php on line 260 PRipple Launched

Compile PATH /home/leideqin/canteen/canteen-app Listen http://127.0.0.1:8008 Threads 4

Master ├─ 85932 Thread Running ├─ 85933 Thread Running ├─ 85934 Thread Running ├─ 85935 Thread Running

The service is not running.

cclilshy commented 3 months ago

这个drive是开发版本吧?用正式版

leideqin commented 3 months ago

这个drive是开发版本吧?用正式版

用的就是最新的正式版,v0.3.1。我的php版本是8.2.19

cclilshy commented 3 months ago

我复现了一下环境

Laravel11 + PHP8.2

这个是v0.3.1存在的问题(主进程无法在非异步空间开启子进程),会在下次更新覆盖这个版本解决

建议的临时方案是

1.降级驱动到v1.1.6版本驱动以适用v0.2

2.修改task方法部分代码作为补丁

Psc\Library\System\Process\Process.php

/**
 * @param Closure $closure
 * @return Task|false
 */
public function task(Closure $closure): Task|false
{
    return new Task(function (...$args) use ($closure) {
        $processId = pcntl_fork();

        if ($processId === -1) {
            Output::warning('Fork failed.');
            return false;
        }

        if ($processId === 0) {
            /**
             * It is necessary to ensure that the final closure cannot be escaped by any means.
             */

            // Whether it belongs to the PRipple coroutine space
            $isCoroutine = Coroutine::Coroutine()->isCoroutine();

            // forget all events
            cancelAll();

            // Handle recycling and new process mounting
            $this->forked();

            // call user mount
            try {
                call_user_func($closure, ...$args);
            } catch (Throwable) {
                exit(1);
            }

            // Determine whether the event list is empty
            if(count(getIdentities()) === 0) {
                exit(0);
            }

            if(!$isCoroutine) {
                if(Fiber::getCurrent()) {
                    Fiber::suspend();
                }
                tick();
                exit(0);
            }

            throw new EscapeException('The process is abnormal.');
        }

        if(empty($this->process2runtime)) {
            $this->registerSignalHandler();
        }

        $promise = promise(function ($r, $d) use ($processId) {
            $this->process2promiseCallback[$processId] = array(
                'resolve' => $r,
                'reject'  => $d,
            );
        });

        $runtime = new Runtime(
            $promise,
            $processId,
        );

        $this->process2runtime[$processId] = $runtime;
        return $runtime;
    });
}
leideqin commented 3 months ago

嗯,降级就可以了