*/ declare(strict_types=1); use BlaxSoftware\LaravelWebSockets\Ipc\SocketPairIpc; use BlaxSoftware\LaravelWebSockets\Server\ChildFatalErrorGuard; use BlaxSoftware\LaravelWebSockets\Websocket\ChildMessageOutcome; use React\EventLoop\StreamSelectLoop; require __DIR__ . '/../../../vendor/autoload.php'; $mode = $argv[1] ?? 'oom'; $loop = new StreamSelectLoop(); $ipc = SocketPairIpc::create($loop); $pid = pcntl_fork(); if ($pid === 0) { $ipc->setupChild(); // Stand-in for Laravel's HandleExceptions: registered earlier (in the // server process), so it runs before the guard and sees the error first. register_shutdown_function(function () { $error = error_get_last(); if ($error !== null) { fwrite(STDERR, 'app handler saw: ' . $error['message'] . "\n"); } }); $frame = json_encode([ 'event' => 'demo.crash:error', 'data' => ['message' => 'Internal server error', 'meta' => ['reported' => true, 'fatal' => true]], 'channel' => 'test', ]); $guard = ChildFatalErrorGuard::register(function () use ($ipc, $frame) { $ipc->sendToParent($frame); }); if ($mode === 'clean-exit') { exit(0); } if ($mode === 'warning-then-exit') { @trigger_error('just a warning', E_USER_WARNING); exit(0); } if ($mode === 'oom-disarmed') { $guard->disarm(); } ini_set('memory_limit', '32M'); $hog = []; while (true) { $hog[] = str_repeat('x', 1024 * 1024); } } $frames = []; $outcome = new ChildMessageOutcome('demo.crash', function () { }); $ipc->setupParent( function ($data) use (&$frames, $outcome) { $frames[] = $data; $outcome->frameReceived($data); }, function () use ($loop) { $loop->stop(); } ); $loop->addTimer(10, function () use ($loop) { $loop->stop(); }); $loop->run(); pcntl_waitpid($pid, $status); echo json_encode([ 'frames' => $frames, 'exit_code' => pcntl_wifexited($status) ? pcntl_wexitstatus($status) : null, 'replied' => $outcome->replied(), ]);