-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
I know it has been asked some times already :
#4594
#3078
How can we implement a real max_execution_time that will free the worker.
One proposed solution was that :
$http->on(
Constant::EVENT_REQUEST,
function (Request $request, Response $response) use () {
echo 'Http request started' . "\n";
Timer::after(5000, function () use ($response) {
$response->status(408);
$response->end('Timeout');
echo 'Timeout has been sent' . "\n";
});
// Actual code that take maybe forever somehow
echo 'We reached the end' . "\n";
$response->status(200);
$response->end('The end');
}
);So indeed the client will receive a 408 timeout.
But the worker is still working and doing things right ? (things that will never reach the end user)
So another implementation could be :
$http->on(
Constant::EVENT_REQUEST,
function (Request $request, Response $response) {
echo 'Http request started' . "\n";
$killRequest = false;
Timer::after(5000, function () use ($response, &$killRequest) {
$response->status(408);
$response->end('Timeout');
echo 'Timeout has been sent' . "\n";
$killRequest = true;
});
echo 'Step 1' . "\n";
sleep(2); // code that takes 2s
if ($killRequest) return;
echo 'Step 2' . "\n";
sleep(2); // code that takes 2s
if ($killRequest) return;
echo 'Step 3' . "\n";
sleep(2); // code that takes 2s
if ($killRequest) return; // we stop here
echo 'Step 4' . "\n";
sleep(2); // code that takes 2s
if ($killRequest) return;
echo 'Step 5' . "\n";
sleep(2); // code that takes 2s
if ($killRequest) return;
echo 'We reached the end' . "\n";
$response->status(200);
$response->end('The end');
}
);The print will be
Http request started
Step 1
Step 2
Step 3
Timeout has been sent
OK that's fine, but that just impossible to do, because we are inside classes doing stuff.
I'm concerned about CPU usage, RAM usage and especially about the workers.
From my test with only 1 worker, if somehow I don't use the database proxy classes, the worker can only treat one request at a time.
Meaning the first request is processing, the second is waiting.
I did the same test with database proxy classes, the second request doesn't wait however.
But I'm still concerned, if somehow all workers are blocked and the server can't receive any new request.
Is this an option that could be implemented in swoole internals ? What do you think ?
(OpenSwoole implemented it but I'm not sure it really works : openswoole/ext-openswoole#136)