Limit php runtime

I am making a request. Someday the answer will be quick, and sometimes more than 10 seconds. My question is: I need to stop the query if it is after 5 seconds and then update the database. So here is the question, how can I get $ip stop after 5 seconds to update my database?

 $host = "@$ns1 $subdomain"; $ip = `/usr/bin/dig $host +short A`; // if $ip is more than 5 sec than stop the query. How to do this? mysql_query("UPDATE dns SET query_ns = '1' WHERE zone ='123'"); 

Update : I am very sorry for any confusion. What I meant by query is using dig to search for ns. Sorry again.

+4
source share
7 answers

You can use proc_open to open the channel in the dig, stream_select command and wait 5 seconds, read after that and close proc.

More or less this way:

 function getip() { $ip = null; $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr ); $process = proc_open("/usr/bin/dig $host +short A", $descriptorspec, $pipes); if (is_resource($process)) { // $pipes now looks like this: // 0 => writeable handle connected to child stdin // 1 => readable handle connected to child stdout // 2 => readable handle $ip = fgetsPending($pipes[1]); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); // It is important that you close any pipes before calling // proc_close in order to avoid a deadlock proc_close($process); } return $ip; } function fgetsPending(&$in,$tv_sec=5) { if ( stream_select($read = array($in),$write=NULL,$except=NULL,$tv_sec) ) return fgets($in); else return FALSE; } echo getip(); 
+3
source

Take a look at the documentation for the mysql_unbuffered_query function: http://www.php.net/manual/en/function.mysql-unbuffered-query.php

Something along these lines should do what you want:

 <?php // a db link for queries $lh = mysql_connect( 'server', 'uname', 'pword' ); // and a controller link $clh = mysql_connect( 'server', 'uname', 'pword', true ); if ( mysql_select_db ( 'big_database', $lh ) ) { $began = time(); $tout = 60 * 5; // five minute limit $qry = "SELECT * FROM my_bigass_table"; $rh = mysql_unbuffered_query( $qry, $lh ); $thread = mysql_thread_id ( $lh ); while ( $res = mysql_fetch_row( $rh ) ) { /* do what you need to do * ... * ... */ if ( ( time() - $began ) > $tout ) { // this is taking too long mysql_query( "KILL $thread", $clh ); break; } } } ?> 
+1
source

Just in the dark, but I would try something like this:

 $default_exe_time = ini_get('max_execution_time'); try { ini_set('max_execution_time', 5); $host = "@$ns1 $subdomain"; $ip = `/usr/bin/dig $host +short A`; if (!mysql_query("UPDATE dns SET query_ns = '1' WHERE zone ='123'")){ throw new Exception(''); } } catch Exception ($e) { // update db } ini_set('max_execution_time', $default_exe_time); 
+1
source

I do not know how to do this with the mysql extension (it does not have such a function or settings), but you can easily deal with mysqli:

 mysqli_options($connection, MYSQLI_OPT_CONNECT_TIMEOUT, 5); 

or OOP method:

 $connection->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); 

You can read about mysqli and its functions here.

+1
source

In the official documentation, "PHP will try to execute the contents of the backlinks as a shell command," which means you must do the following:

 $ip = `/usr/bin/dig $host +short A & pid=$! ; sleep 5; kill -9 $pid` 

This trick works in the shell, so if PHP does the reverse steps in the shell, you should be good.

EDIT: You may need to apply extra polish so that PHP doesn't try to extend $pid ...

+1
source

You can switch to using mysqli and use the mysqli_kill() command: http://php.net/manual/en/mysqli.kill.php

0
source

The problem is solved and thanks to ajreal in order to give me his idea. Instead, I decided to limit the request to dig utilities. Solution: https://serverfault.com/questions/360102/dig-timeout-option-dont-work

Thanks for the help and contribution.

0
source

Source: https://habr.com/ru/post/1396441/


All Articles