hyperf / hyperf

🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.

Home Page:https://www.hyperf.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] Coroutines deadlock when using hyperf/signal's WorkerStopHandler

leocavalcante opened this issue · comments

Linux codespaces-64bc14 6.2.0-1019-azure #19~22.04.1-Ubuntu SMP Wed Jan 10 22:57:03 UTC 2024 x86_64 Linux
PHP 8.3.3 (cli) (built: Feb 16 2024 01:31:30) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.3, Copyright (c), by Zend Technologies
hyperf/cache                       v3.1.15 A cache component for hyperf.
hyperf/code-parser                 v3.1.15 A code parser component for Hyperf.
hyperf/codec                       v3.1.15 A codec component for Hyperf.
hyperf/collection                  v3.1.15 Hyperf Collection package which come from illuminate/collections
hyperf/command                     v3.1.15 Command for hyperf
hyperf/conditionable               v3.1.15 Hyperf Macroable package which come from illuminate/conditionable
hyperf/config                      v3.1.15 An independent component that provides configuration container.
hyperf/context                     v3.1.15 A coroutine/application context library.
hyperf/contract                    v3.1.15 The contracts of Hyperf.
hyperf/coordinator                 v3.1.15 Hyperf Coordinator
hyperf/coroutine                   v3.1.15 Hyperf Coroutine
hyperf/database                    v3.1.15 A flexible database library.
hyperf/db-connection               v3.1.15 A hyperf db connection handler for hyperf/database.
hyperf/devtool                     v3.1.15 A Devtool for Hyperf.
hyperf/di                          v3.1.15 A DI for Hyperf.
hyperf/dispatcher                  v3.1.15 A HTTP Server for Hyperf.
hyperf/engine                      v2.10.5 Coroutine engine provided by swoole.
hyperf/engine-contract             v1.9.1  Contract for Coroutine Engine
hyperf/event                       v3.1.15 an event manager that implements PSR-14.
hyperf/exception-handler           v3.1.15 Exception handler for hyperf
hyperf/framework                   v3.1.15 A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.
hyperf/guzzle                      v3.1.15 Swoole coroutine handler for guzzle
hyperf/http-message                v3.1.15 microservice framework base on swoole
hyperf/http-server                 v3.1.15 A HTTP Server for Hyperf.
hyperf/logger                      v3.1.15 A logger component for hyperf.
hyperf/macroable                   v3.1.15 Hyperf Macroable package which come from illuminate/macroable
hyperf/memory                      v3.1.15 An independent component that use to operate and manage memory.
hyperf/model-listener              v3.1.15 A model listener for Hyperf.
hyperf/pipeline                    v3.1.15 Hyperf Macroable package which come from illuminate/pipeline
hyperf/pool                        v3.1.15 An independent universal connection pool component.
hyperf/process                     v3.1.15 A process component for hyperf.
hyperf/redis                       v3.1.15 A redis component for hyperf.
hyperf/serializer                  v3.1.15 A serializer component for Hyperf.
hyperf/server                      v3.1.15 A base server library for Hyperf.
hyperf/signal                      v3.1.15 A signal library for Hyperf.
hyperf/stdlib                      v3.1.15 A stdlib component for Hyperf.
hyperf/stringable                  v3.1.15 Hyperf Stringable package which come from illuminate/support
hyperf/support                     v3.1.15 A support component for Hyperf.
hyperf/tappable                    v3.1.15 Hyperf Macroable package which come from illuminate/tappable
hyperf/testing                     v3.1.15 Testing for hyperf
hyperf/utils                       v3.1.0  A tools package that could help developer solved the problem quickly.

swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 5.1.2
Built => Feb 18 2024 03:07:09
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 3.1.4 24 Oct 2023
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
c-ares => 1.24.0
zlib => 1.3.1
brotli => E16781312/D16781312
mutex_timedlock => enabled
pthread_barrier => enabled
async_redis => enabled
coroutine_pgsql => enabled
coroutine_odbc => enabled
coroutine_sqlite => 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 => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608

Description:

Getting coroutines deadlock when trying to use the WorkerStopHandler:

^C
===================================================================
 [FATAL ERROR]: all coroutines (count: 2) are asleep - deadlock!
===================================================================

 [Coroutine-3]
--------------------------------------------------------------------
#0 /workspaces/hyperf-skeleton/vendor/hyperf/engine/src/Signal.php(22): Swoole\Coroutine\System::waitSignal()
#1 /workspaces/hyperf-skeleton/vendor/hyperf/signal/src/SignalManager.php(69): Hyperf\Engine\Signal::wait()
#2 /workspaces/hyperf-skeleton/vendor/hyperf/coroutine/src/Coroutine.php(80): Hyperf\Signal\SignalManager->Hyperf\Signal\{closure}()
#3 [internal function]: Hyperf\Coroutine\Coroutine::Hyperf\Coroutine\{closure}()


 [Coroutine-2]
--------------------------------------------------------------------
#0 /workspaces/hyperf-skeleton/vendor/hyperf/engine/src/Signal.php(22): Swoole\Coroutine\System::waitSignal()
#1 /workspaces/hyperf-skeleton/vendor/hyperf/signal/src/SignalManager.php(69): Hyperf\Engine\Signal::wait()
#2 /workspaces/hyperf-skeleton/vendor/hyperf/coroutine/src/Coroutine.php(80): Hyperf\Signal\SignalManager->Hyperf\Signal\{closure}()
#3 [internal function]: Hyperf\Coroutine\Coroutine::Hyperf\Coroutine\{closure}()


===================================================================
 [FATAL ERROR]: all coroutines (count: 2) are asleep - deadlock!
===================================================================

 [Coroutine-3]
--------------------------------------------------------------------
#0 /workspaces/hyperf-skeleton/vendor/hyperf/engine/src/Signal.php(22): Swoole\Coroutine\System::waitSignal()
#1 /workspaces/hyperf-skeleton/vendor/hyperf/signal/src/SignalManager.php(69): Hyperf\Engine\Signal::wait()
#2 /workspaces/hyperf-skeleton/vendor/hyperf/coroutine/src/Coroutine.php(80): Hyperf\Signal\SignalManager->Hyperf\Signal\{closure}()
#3 [internal function]: Hyperf\Coroutine\Coroutine::Hyperf\Coroutine\{closure}()


 [Coroutine-2]
--------------------------------------------------------------------
#0 /workspaces/hyperf-skeleton/vendor/hyperf/engine/src/Signal.php(22): Swoole\Coroutine\System::waitSignal()
#1 /workspaces/hyperf-skeleton/vendor/hyperf/signal/src/SignalManager.php(69): Hyperf\Engine\Signal::wait()
#2 /workspaces/hyperf-skeleton/vendor/hyperf/coroutine/src/Coroutine.php(80): Hyperf\Signal\SignalManager->Hyperf\Signal\{closure}()
#3 [internal function]: Hyperf\Coroutine\Coroutine::Hyperf\Coroutine\{closure}()

Steps To Reproduce:

From a fresh start, just:

composer require hyperf/signal
php bin/hyperf.php vendor:publish hyperf/signal

At config/autoload/signal.php, uncomment the line:

Hyperf\Signal\Handler\WorkerStopHandler::class => PHP_INT_MIN

Start the application regurlarly with php bin/hyperf.php start, then try to stop with SIGINT (Ctrl + C).

Hi @leocavalcante ,

This issue may be duplicated to #3150 and #4230. And based on those previous comments, this message seems an expected behaviour in Swoole's deadlock_check config.

Maybe you can disable this check before workers shutting down. In this way it can disable this error message and remain deadlock checks while your application running.

like this:

class WorkerStopHandler extends HyperfWorkerStopHandler
{
    public function handle(int $signal): void
    {
        Coroutine::set([
            'enable_deadlock_check' => false,
        ]);

        parent::handle($signal);
    }
}

Thank you, @albertcht. I'll ignore it as suggested in previous similar issues.