Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set_time_limit() counts time while pg_get_result() waiting for asynchronous PostgreSQL query #14769

Closed
lezso6 opened this issue Jul 2, 2024 · 17 comments

Comments

@lezso6
Copy link

lezso6 commented Jul 2, 2024

Description

The following code:

<?php
// Connect
$conn = pg_connect("dbname='somedb'");
// Send a postgres sleep query (or anything long running query)
pg_send_query($conn, "SELECT pg_sleep(5)");
// Set PHP max execution time less than above
set_time_limit(2);
// Waiting for query to complete (but fails and error is shown)
$res = pg_get_result($conn); 
// Never printed
echo "OK"; 

Resulted in this output:

PHP Fatal error: maximum execution time of 2 seconds exceeded

But I expected this output instead:

OK

PHP Version

8.3.8

Operating System

Gentoo Linux

@lezso6
Copy link
Author

lezso6 commented Jul 2, 2024

The code worked as expected in PHP 8.1, until I upgraded to PHP 8.3. I think it should not count time while the PHP script is doing nothing but waiting for the PostgreSQL server. I did not find any documentation about this change in code behaviour.

@devnexen
Copy link
Member

devnexen commented Jul 2, 2024

I have tried with the following cases :

  • last master built on ubuntu 24.04 on local pgsql server.
  • 8.3.6 from same ubuntu with same server.
  • 8.3.8 from macOs remote connection on this same pgsql server.

In every case I get my OK.

@lezso6
Copy link
Author

lezso6 commented Jul 2, 2024

Thanks for the quick reply. Indeed, the code works as it should on Ubuntu, I tried it too. I have two very different Gentoo systems with PHP 8.3 and both produces the bug. I also tested PHP 8.2 on Gentoo (same configuration) and got the OK. It's weird, seems like a Gentoo specific bug on version 8.3.

@MorganLOCode
Copy link

As another datapoint, 8.3.8 on Windows times out as well.

@lezso6
Copy link
Author

lezso6 commented Jul 3, 2024

I tried version 8.3.6 and 8.3.3 on Gentoo and both throws the error.

@lezso6
Copy link
Author

lezso6 commented Jul 3, 2024

I think I found the problem, the error depends on whether thread safety is enabled or not. If I compile PHP 8.3.8 on Gentoo without threads, the above code works as should. But if I compile PHP with POSIX threads, the code breaks. On Ubuntu the PHP 8.3.6 is compiled without threads, that's why it's working okay.

@devnexen
Copy link
Member

devnexen commented Jul 3, 2024

does it work with ZTS and in a non async way ? e.g. just pg_query

@lezso6
Copy link
Author

lezso6 commented Jul 3, 2024

Suprisingly, the script times out in non-async / blocking mode too:

<?php
$conn = pg_connect("host='127.0.0.1' port='5432' dbname='template1' user='postgres'");
ini_set('display_errors', '1');
// Setting execution time less than below
set_time_limit(2);
// PHP Fatal error: maximum execution time of 2 seconds exceeded
pg_query($conn, "SELECT pg_sleep(5)");
// Never printed
echo "OK";

@devnexen devnexen self-assigned this Jul 5, 2024
@devnexen
Copy link
Member

devnexen commented Jul 5, 2024

I ll have a look in the following days.

@devnexen
Copy link
Member

devnexen commented Jul 7, 2024

Anybody using mysql ? If yes what happens with ZTS build with 'SELECT SLEEP(5)' query?

@lezso6
Copy link
Author

lezso6 commented Jul 7, 2024

I tried mysqli extension with MariaDB and the PHP script times out as well. Code:

<?php
ini_set('display_errors', '1');
echo PHP_VERSION . "\n";
$conn = mysqli_connect('127.0.0.1', 'root', '1234');
// Setting execution time less than SLEEP()
set_time_limit(2);
// PHP Fatal error: maximum execution time of 2 seconds exceeded
mysqli_query($conn, "SELECT SLEEP(5)");
// Never printed
echo "OK"; 

@lezso6
Copy link
Author

lezso6 commented Jul 7, 2024

Even PHP's sleep() function times out with ZTS enabled:

<?php
ini_set('display_errors', '1');
echo PHP_VERSION . "\n";
// Setting execution time less than PHP sleep()
set_time_limit(2);
// PHP Fatal error: maximum execution time of 2 seconds exceeded
sleep(5);
// Never printed
echo "OK"; 

Without ZTS, there is no timeout.

@devnexen
Copy link
Member

devnexen commented Jul 7, 2024

Ok gonna bisect it. I think that s better support Linux timeouts with ZTS part but will double-check.

@devnexen
Copy link
Member

devnexen commented Jul 7, 2024

Was wrong about the commit, @lezso6, if you build from source, can you add --enable-zend-max-execution-timers=no to the ./configure command ? I forgot about that change ..

@lezso6
Copy link
Author

lezso6 commented Jul 8, 2024

I recompiled with ZTS enabled and Zend Max Execution Timers disabled, and the bug is gone. It works, no timeouts.

@devnexen
Copy link
Member

devnexen commented Jul 8, 2024

It appears on the migration guide. Distribution packagers would need to modify their build workflow to take it into account.

@devnexen devnexen closed this as completed Jul 8, 2024
@lezso6
Copy link
Author

lezso6 commented Jul 8, 2024

So if I understand correctly, this is a feature. And will be enabled for non-ZTS builds, I read that here: #6504 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants