swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.47k stars 3.16k forks source link

Server deadlock when using max_concurrency #5407

Closed allsilaevex closed 4 months ago

allsilaevex commented 4 months ago

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error.
<?php

$server = new Swoole\Http\Server('0.0.0.0', 9999);

$server->set([
    'worker_num' => 2,
    'max_concurrency' => 8,
    'worker_max_concurrency' => 4,
]);

$server->on('request', function ($request, $response) {
    Swoole\Coroutine::sleep(.1);
    throw new RuntimeException('any unhandled exception');
});

$server->start();

You can reproduce the error using the following steps:

curl -I http://0.0.0.0:9999 # HTTP/1.1 500 Internal Server Error

wrk -t 4 -c 16 -d1s http://0.0.0.0:9999

curl -I http://0.0.0.0:9999 # HTTP/1.1 503 Service Unavailable
  1. What did you expect to see?

After running wrk I expect to see:

curl -I http://0.0.0.0:9999 # HTTP/1.1 500 Internal Server Error
  1. What did you see instead?

After running wrk I see:

curl -I http://0.0.0.0:9999 # HTTP/1.1 503 Service Unavailable
  1. What version of Swoole are you using (show your php --ri swoole)?
0d2d4b0e30df:/app$ php --ri swoole

swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 5.1.2
Built => Jun  4 2024 09:09:32
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 3.3.0 9 Apr 2024
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
c-ares => 1.28.1
zlib => 1.3.1
brotli => E16781312/D16781312
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
0d2d4b0e30df:/app$ uname -a
Linux 0d2d4b0e30df 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64 Linux
0d2d4b0e30df:/app$ php -v
PHP 8.3.7 (cli) (built: May 22 2024 23:46:10) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.7, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.7, Copyright (c), by Zend Technologies
0d2d4b0e30df:/app$ gcc -v
bash: gcc: command not found
NathanFreeman commented 4 months ago

Exceptions thrown in coroutines need to be caught using try-catch, or it will cause the process to exit. https://wiki.swoole.com/en/#/getting_started/notice?id=capturing-runtime-exceptionserrors-in-coroutine

allsilaevex commented 4 months ago

@NathanFreeman you're right, but should terminating the process for any reason cause a deadlock on the server?

it seems that even if the process was terminated, the concurrency value should decrease and the server should continue accepting requests (since a new process is created) but concurrency decreases only in swoole_http_server_onAfterResponse - it doesn't take into account process crashing

NathanFreeman commented 4 months ago

I reproduced it, let me see how to resolve it.