Skip to content

Package is Causing Open Swoole Server Shut Down Process Failure #25

@AmitSonkhiya

Description

@AmitSonkhiya

First of all, thank you for the package.
It reloads the server as expected when any file in given paths changes.

However, the script is also causing failure in shutting down the Open Swoole server.
When the watcher is not enabled, Swoole server start and shutdown processes work as expected (called through commands).
However, when the watcher is in the place, it doesn't let the server go shutdown even if you have stopped the watcher.

I have created a very simple and ready to run script (given in the end) to observe the behavior.

Steps to produce

  1. Save the code in a file named wss.php

  2. Watcher start() and stop() events are commented out initially.

  3. Edit the $cfg array as per your installation and save changes.

  4. First test if the server is starting and shutting down as expected without the watcher

  5. It would be great to give 1 or 2 seconds gap between running each command.

  6. Run the command: php /home/wss.php start

  7. Run the command: php /home/wss.php shutdown

  8. Run the command: php /home/wss.php start

  9. The server start, shutdown, and start processes would go smoothly.

  10. Now enable the watcher and test the same.

  11. Remove comments before line number 50 and 53.

  12. Run the 3 commands in sequence, start, shutdown, start

  13. On the second start, the terminal would throw error:

Uncaught Swoole\Exception: failed to listen server port[127.0.0.1:9000], Error: Address already in use[98] in /home/wss.php:30

Expected behavior

The server shutdown and further start processes should be succeed as expected.

Observed behavior

The server shutdown process halts and further start process complaints that the port is already in use.

Uncaught Swoole\Exception: failed to listen server port[127.0.0.1:9000], Error: Address already in use[98] in /home/wss.php:30

_Stack trace:
-0 /home/wss.php(30): Swoole\Server->__construct()
-1 /home/wss.php(79): Wss->_construct()
-2 {main}
thrown in /home/wss.php on line 30

Environment

OS: CentOS 8 Stream
PHP version: 8.1
Open Swoole version: 4.11.1

Ready script

<?php

use Swoole\WebSocket\Server;
use RTC\Watcher\Watcher;
use Swoole\Runtime;
use Swoole\Coroutine\Http\Client;

class Wss
{
    // Configuration
    public $cfg;
    // Server
    public $server;
    // Watcher
    public $watcher;

    public function __construct()
    {
        $this->cfg = [
            'rtcDir' => __DIR__ . '/vendor/autoload.php',
            'serverType' => SWOOLE_SOCK_TCP | SWOOLE_SSL,
            'watchDir' => __DIR__ . '/app',
            'sslCert' => 'website.cert',
            'sslKey' => 'website.key',
            'logFile' => __DIR__ . '/swoole.log',
        ];
        
        require_once $this->cfg['rtcDir'];

        $this->server = new Server('127.0.0.1', 9000, SWOOLE_PROCESS, $this->cfg['serverType']);

        // Auto reload server when file changes
        $this->watcher = Watcher::create()
            ->addPath($this->cfg['watchDir'])
            ->onChange(fn() => $this->server->reload());

        $this->server->set([
            'daemonize' => 2,
        
            'ssl_cert_file' => $this->cfg['sslCert'],
            'ssl_key_file' => $this->cfg['sslKey'],
        
            // 'log_level' => SWOOLE_LOG_DEBUG,
            'log_file' => $this->cfg['logFile'],
            'log_date_format' => '%d-%m-%Y %H:%M:%S',
        ]);

        $this->server->on('Start', function ($svr) {
            echo 'Server is started at ' . $svr->host . ': ' . $svr->port . PHP_EOL;
            // $this->watcher->start();
        });

        // $this->server->on('Shutdown', fn($svr) => $this->watcher->stop());
        
        $this->server->on('Request', function ($req, $res) {
            if (isset($req->post['action']) && in_array($req->post['action'], ['reload', 'shutdown'])) {
                $res->end('Processing '. $req->post['action']);
                $this->server->{$req->post['action']}();
            } else {
                $res->end('<h1>Hello World!</h1><h3>from Server.</h3>');
            }
        });

        $this->server->on('Open', function ($svr, $req) {
            $svr->tick(5000, fn() => $svr->push($req->fd, json_encode(['hello', time()])));
        });

        $this->server->on('Message', fn($svr, $frame) => $svr->push($frame->fd, 'ok'));
    }

    public function start()
    {
        $this->server->start();
    }
}

if ('start' === $argv[1]) {
    Runtime::enableCoroutine(true);
    (new Wss())->start();
} elseif ('shutdown' === $argv[1] || 'reload' === $argv[1]) {
    $arg = $argv[1];
    \Co\run(function () use ($arg) {
        $client = new Client('127.0.0.1', 9000, true);
        $client->setHeaders([
            'Accept' => 'text/html,application/json',
            'Accept-Encoding' => 'gzip',
            'Host' => 'localhost',
            'User-Agent' => 'Coroutine',
        ]);

        $client->post('/', ['action'=> $arg]);
        $client->close();
        if ($client->errCode ?? false) {
            echo 'Error: '. $client->errCode .', '. $client->errMsg . PHP_EOL;
        }
    });
} else {
    echo 'Incorrect argument' . PHP_EOL;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions