Please answer these questions before submitting your issue. Thanks!
<?php
$http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_PROCESS);
$http->set([
'worker_num' => 1,
'dispatch_mode' => 1,
]);
$http->on('start', function ($server) {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
});
$http->on('request', function ($request, $response) use ($http) {
$response->header('Content-Type', 'application/pdf');
$fd = fopen('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf', 'r');
while(!feof($fd)) {
$data = fread($fd, 1024);
// some long process with $data
sleep(1);
!empty($data) && $response->write($data);
// Uncomment to achieve paralelism
// co::sleep(0.001);
if (!$http->exist($response->fd)) {
throw new \Exception('Client lost');
}
}
$response->end();
});
$http->start();
I'm expecting to be able to start 2 or more downloads (ie: curl http://localhost:9501 -o test1.pdf) after some processing on a remote file (reading + encrypting + writing on response).
The number of simultaneous downloads is limited by the worker_num.
With co::sleep, I'm able to get paralelism because co::sleep allows to the scheduler to use the cpu for another coroutines. The problem is that with co::sleep I'm getting a lower download rate, possible due the interruptions.
Is there another way to _"invite"_ to the scheduler to switch to another coroutines?
Congratulations by the amazing work you've done.
php --ri swoole)?$ php --ri swoole
swoole
Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 4.2.13
Built => Aug 6 2019 13:14:08
coroutine => enabled
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.0.2r 26 Feb 2019
pcre => enabled
zlib => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled
Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.fast_serialize => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608
$ php -v
PHP 7.3.7 (cli) (built: Aug 6 2019 11:40:40) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.7, Copyright (c) 1999-2018, by Zend Technologies
$ uname -r
4.19.57-gentoo
$ gcc --version
gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
you are using synchronous read in your handler. change to async
Please answer these questions before submitting your issue. Thanks!
- What did you do? If possible, provide a simple script for reproducing the error.
<?php $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_PROCESS); $http->set([ 'worker_num' => 1, 'dispatch_mode' => 1, ]); $http->on('start', function ($server) { echo "Swoole http server is started at http://127.0.0.1:9501\n"; }); $http->on('request', function ($request, $response) use ($http) { $response->header('Content-Type', 'application/pdf'); $fd = fopen('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf', 'r'); while(!feof($fd)) { $data = fread($fd, 1024); // some long process with $data sleep(1); !empty($data) && $response->write($data); // Uncomment to achieve paralelism // co::sleep(0.001); if (!$http->exist($response->fd)) { throw new \Exception('Client lost'); } } $response->end(); }); $http->start();
- What did you expect to see?
I'm expecting to be able to start 2 or more downloads (ie: curl http://localhost:9501 -o test1.pdf) after some processing on a remote file (reading + encrypting + writing on response).
- What did you see instead?
The number of simultaneous downloads is limited by the worker_num.
With co::sleep, I'm able to get paralelism because co::sleep allows to the scheduler to use the cpu for another coroutines. The problem is that with co::sleep I'm getting a lower download rate, possible due the interruptions.
Is there another way to _"invite"_ to the scheduler to switch to another coroutines?
Congratulations by the amazing work you've done.
- What version of Swoole are you using (show your
php --ri swoole)?$ php --ri swoole swoole Swoole => enabled Author => Swoole Team <[email protected]> Version => 4.2.13 Built => Aug 6 2019 13:14:08 coroutine => enabled epoll => enabled eventfd => enabled signalfd => enabled cpu_affinity => enabled spinlock => enabled rwlock => enabled openssl => OpenSSL 1.0.2r 26 Feb 2019 pcre => enabled zlib => enabled mutex_timedlock => enabled pthread_barrier => enabled futex => enabled async_redis => enabled Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.display_errors => On => On swoole.use_shortname => On => On swoole.fast_serialize => Off => Off swoole.unixsock_buffer_size => 8388608 => 8388608
- What is your machine environment used (including version of kernel & php & gcc) ?
$ php -v PHP 7.3.7 (cli) (built: Aug 6 2019 11:40:40) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.3.7, Copyright (c) 1999-2018, by Zend Technologies$ uname -r 4.19.57-gentoo$ gcc --version gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
hi,please open the runtime hook.
like this:
\Swoole\Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
<?php
\Swoole\Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
$http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_PROCESS);
$http->set([
'worker_num' => 1,
'dispatch_mode' => 1,
]);
$http->on('start', function ($server) {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
});
$http->on('request', function ($request, $response) use ($http) {
$response->header('Content-Type', 'application/pdf');
$fd = fopen('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf', 'r');
while (!feof($fd)) {
$data = fread($fd, 1024);
// some long process with $data
sleep(1);
!empty($data) && $response->write($data);
// Uncomment to achieve paralelism
// co::sleep(0.001);
if (!$http->exist($response->fd)) {
throw new \Exception('Client lost');
}
}
$response->end();
});
$http->start();
The line added makes the difference.
Thank you very much.
Most helpful comment