swoole / swoole-src

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

curl_multi_add_handle - The given object is not a valid coroutine CurlMultiHandle object #4827

Closed Gemorroj closed 1 year ago

Gemorroj commented 1 year ago

reopen https://github.com/swoole/swoole-src/issues/4522 (still reproduce)

  1. What did you do? If possible, provide a simple script for reproducing the error. I try to send http requests using symfony/http-client and https://github.com/php-runtime/swoole Here an example project https://github.com/Gemorroj/test-swoole-symfony (take a look https://github.com/Gemorroj/test-swoole-symfony/blob/main/src/Controller/TestController.php#L63 for example)

  2. What did you expect to see? parallel work

  3. What did you see instead?

    php_1  | Fatal error: Uncaught Swoole\Error: The given object is not a valid coroutine CurlMultiHandle object in /var/www/app/vendor/symfony/http-client/Response/CurlResponse.php:176
    php_1  | Stack trace:
    php_1  | #0 /var/www/app/vendor/symfony/http-client/Response/CurlResponse.php(176): curl_multi_add_handle(Object(CurlMultiHandle), Object(CurlHandle))
    php_1  | #1 /var/www/app/vendor/symfony/http-client/CurlHttpClient.php(318): Symfony\Component\HttpClient\Response\CurlResponse->__construct(Object(Symfony\Component\HttpClient\Internal\CurlClientState), Object(CurlHandle), Array, NULL, 'GET', Object(Closure), 479232)
    php_1  | #2 /var/www/app/vendor/symfony/http-client/ScopingHttpClient.php(93): Symfony\Component\HttpClient\CurlHttpClient->request('GET', 'https://httpbin...', Array)
    php_1  | #3 /var/www/app/src/Controller/TestController.php(134): Symfony\Component\HttpClient\ScopingHttpClient->request('GET', 'https://httpbin...')
    php_1  | #4 @swoole-src/library/core/Coroutine/functions.php(37): App\Controller\TestController::App\Controller\{closure}()
    php_1  | #5 {main}
    php_1  |   thrown in /var/www/app/vendor/symfony/http-client/Response/CurlResponse.php on line 176
  4. What version of Swoole are you using (show your php --ri swoole)? master

    
    /var/www/app # php --ri swoole

swoole

Swoole => enabled Author => Swoole Team team@swoole.com Version => 5.0.0 Built => Sep 7 2022 14:58:49 coroutine => enabled with boost asm context epoll => enabled eventfd => enabled signalfd => enabled spinlock => enabled rwlock => enabled sockets => enabled openssl => OpenSSL 1.1.1q 5 Jul 2022 dtls => enabled http2 => enabled json => enabled curl-native => enabled pcre => enabled zlib => 1.2.12 brotli => E16777225/D16777225 mutex_timedlock => enabled pthread_barrier => enabled mysqlnd => enabled async_redis => enabled

Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.enable_library => On => On swoole.enable_preemptive_scheduler => Off => Off swoole.display_errors => On => On swoole.use_shortname => On => On swoole.unixsock_buffer_size => 8388608 => 8388608


5. What is your machine environment used (show your `uname -a` & `php -v` & `gcc -v`) ?
it's docker-win (Host - Win10x64, Conatainer - Alpine Linux 3.16)
data from container:

Linux 3055b652e801 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 Linux

PHP 8.1.10 (cli) (built: Sep 1 2022 21:39:29) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.10, Copyright (c) Zend Technologies

gcc: not found

wdaglb commented 1 year ago

I also appeared!

swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.8.12
Built => Oct 11 2022 09:01:51
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.1.1g FIPS  21 Apr 2020
dtls => enabled
http2 => enabled
curl-native => enabled
pcre => enabled
zlib => 1.2.11
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608

uname -a

Linux iZwz9fp23rp007v5nltj99Z 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

php -v

PHP 8.0.20 (cli) (built: Jun 10 2022 02:13:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.20, Copyright (c) Zend Technologies

gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --disable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC)
mrAndersen commented 1 year ago

Same issue here, swoole from master

PHP 8.1.12 (cli) (built: Nov 12 2022 09:00:50) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.1.12, Copyright (c) Zend Technologies
    with Xdebug v3.1.6, Copyright (c) 2002-2022, by Derick Rethans
matyhtf commented 1 year ago

@Gemorroj @mrAndersen Can you provide a phpt test script that can reproduce the symfony http-client issue

Reference https://github.com/swoole/swoole-src/blob/master/tests/swoole_curl/symfony.phpt

Yurunsoft commented 1 year ago

You cannot use the same $httpClient object in multiple Coroutines at the same time

matyhtf commented 1 year ago

@Gemorroj You should create an httpclient for each request instead of using the same httpclient for multiple concurrent requests.


use Swoole\Runtime;
use Symfony\Component\HttpClient\ScopingHttpClient as SymfonyScopingHttpClient;
use Symfony\Component\HttpClient\HttpClient as SymfonyHttpClient;

use Swoole\Coroutine\WaitGroup;
use function Swoole\Coroutine\run;

Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);

run(function () {

    $wg = new WaitGroup();
    $results = [];
    $args = ['1', '2', '3'];

    foreach ($args as $arg) {
        go(function () use ($wg, $arg, &$results) {
            $wg->add();
            $httpClient = SymfonyScopingHttpClient::forBaseUri(SymfonyHttpClient::create(), 'http://httpbin.org', [
                'max_duration' => 5,
                'headers' => [
                    'Accept' => 'application/json',
                ],
            ]);
            $results[] = $httpClient->request('GET', '/get?key='.$arg)->toArray();
            $wg->done();
        });
    }

    $wg->wait(5);

    Assert::count($results, \count($args));
    foreach ($results as $result) {
        Assert::notEmpty($result);
        Assert::oneOf($result['args']['key'], $args);
    }

    echo 'Done' . PHP_EOL;
});