dunglas / frankenphp

🧟 The modern PHP app server
https://frankenphp.dev
MIT License
6.92k stars 239 forks source link

Unexpected termination, restarting #318

Open RikudouSage opened 11 months ago

RikudouSage commented 11 months ago

I get this error after just trying to run an app in worker mode.

It prints this error all over in the log:

{"level":"error","ts":1700923502.7101762,"msg":"unexpected termination, restarting","worker":"/app/public/index.php","exit_status":255}

It's running in docker (using docker compose):

  webserver:
    image: dunglas/frankenphp
    environment:
      FRANKENPHP_CONFIG: worker ./public/index.php
      APP_RUNTIME: Runtime\\FrankenPhpSymfony\\Runtime
    volumes:
      - $PWD:/app
    ports:
      - "8001:443"
dunglas commented 11 months ago

Could you show your composer.json file? It looks like your worker isn't working properly.

RikudouSage commented 11 months ago

I've reset the changes, so the runtime is not there now, but when I tested it, it was installed there.

composer.json

dunglas commented 11 months ago

The runtime/frankenphp-symfony package looks missing.

Can you install it and be sure to follow this documentation to see if the problem persists? https://github.com/dunglas/frankenphp/blob/main/docs/worker.md#symfony-runtime

RikudouSage commented 11 months ago

As I said, this is reverted to the original version before trying FrankenPHP and the runtime was there when I tried it.

dunglas commented 11 months ago

If possible could you provide a reproducer? It's hard to tell without seeing/trying the code.

RikudouSage commented 11 months ago

I'll try.

aglowienka commented 10 months ago

I had the same. The docs is saying:

docker run \
    -e FRANKENPHP_CONFIG="worker ./public/index.php" \
    -e APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime \
    -v $PWD:/app \
    -p 80:80 -p 443:443 \
    dunglas/frankenphp

When I've changed double slash to single one in APP_RUNTIME it worked:

    -e APP_RUNTIME='Runtime\FrankenPhpSymfony\Runtime' \
pierresh commented 10 months ago

Hello,

I also meet this problem when using the worker mode on a new tiny vanilla PHP project (for testing purposes), although the index.php works well in standard mode.

{"level":"error","ts":1705486764.5677447,"msg":"unexpected termination, restarting","worker":"/app/public/index.php","exit_status":255}

After a few seconds, it eventually terminates with the following error

<br />
<b>Fatal error</b>:  Could not create timer: Resource temporarily unavailable (11) in <b>Unknown</b> on line <b>0</b><br />

My composer.json is empty (no dependency installed):

{
    "config": {
    }
}

My index.php, inspired by the template for custom apps:

<?php

class Kernel
{
    public function boot()
    {
        echo 'Boot';
    }

    public function handle($get, $post, $cookie, $files, $server)
    {
        echo '<br>Handle: ' . Date('Y-m-d H:i:s');
    }

    public function terminate()
    {
        echo '<br>Terminate';
    }

    public function shutdown()
    {
        echo '<br>Shutdown';
    }
}

$myApp = new \Kernel();
$myApp->boot();

$handler = static function () use ($myApp) {
    echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
};

for (
    $nbRequests = 0, $running = true;
    isset($_SERVER['MAX_REQUESTS']) &&
    $nbRequests < ((int) $_SERVER['MAX_REQUESTS']) &&
    $running;
    ++$nbRequests
) {
    $running = \frankenphp_handle_request($handler);

    $myApp->terminate();

    gc_collect_cycles();
}

// Cleanup
$myApp->shutdown();
pierresh commented 10 months ago

Hello,

I also meet this problem when using the worker mode on a new tiny vanilla PHP project (for testing purposes), although the index.php works well in standard mode.

{"level":"error","ts":1705486764.5677447,"msg":"unexpected termination, restarting","worker":"/app/public/index.php","exit_status":255}

After a few seconds, it eventually terminates with the following error

<br />
<b>Fatal error</b>:  Could not create timer: Resource temporarily unavailable (11) in <b>Unknown</b> on line <b>0</b><br />

My composer.json is empty (no dependency installed):

{
    "config": {
    }
}

My index.php, inspired by the template for custom apps:

<?php

class Kernel
{
    public function boot()
    {
        echo 'Boot';
    }

    public function handle($get, $post, $cookie, $files, $server)
    {
        echo '<br>Handle: ' . Date('Y-m-d H:i:s');
    }

    public function terminate()
    {
        echo '<br>Terminate';
    }

    public function shutdown()
    {
        echo '<br>Shutdown';
    }
}

$myApp = new \Kernel();
$myApp->boot();

$handler = static function () use ($myApp) {
    echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
};

for (
    $nbRequests = 0, $running = true;
    isset($_SERVER['MAX_REQUESTS']) &&
    $nbRequests < ((int) $_SERVER['MAX_REQUESTS']) &&
    $running;
    ++$nbRequests
) {
    $running = \frankenphp_handle_request($handler);

    $myApp->terminate();

    gc_collect_cycles();
}

// Cleanup
$myApp->shutdown();

I can make my script work if I change the lines

for (
    $nbRequests = 0, $running = true;
    isset($_SERVER['MAX_REQUESTS']) &&
    $nbRequests < ((int) $_SERVER['MAX_REQUESTS']) &&
    $running;
    ++$nbRequests
) {

to

for (
    $nbRequests = 0, $running = true;
    $nbRequests < 5 && $running;
    ++$nbRequests
) {

The problem is related to _$_SERVER['MAXREQUESTS']; which is undefined.

nikspyratos commented 9 months ago

I'm having this on macOS with Laravel & Octane.

withinboredom commented 9 months ago

Could not create timer: Resource temporarily unavailable

This is due to #440 and is fixed upstream in PHP, but not released yet.

The problem is related to _$SERVER['MAX_REQUESTS']; which is undefined.

Digging around a bit, I think you need to set the env in the caddyfile to get this to work.

Try setting your FRANKENPHP_CONFIG to something like:

FRANKENPHP_CONFIG="worker /path/to/script.php \
env MAX_REQUESTS 25"
rikwillems commented 7 months ago

I had a similar situation. Depending on how you run your app you need to define the environment variable MAX_REQUESTS somewhere. Also you can add $_SERVER['MAX_REQUESTS'] ??= 500; before your for loop as a fallback.