Change to timeout use

From: Date: Wed, 21 Dec 2005 15:49:56 +0000
Subject: Change to timeout use
Groups: php.internals 
Request: Send a blank email to internals+get-21302@lists.php.net to get a copy of this message
Hi all, I am new to php source code hacking, but got into it for a particular reason: I need sub-second SOAP request timeouts. To qualify the reasoning behind this sub-second timeout requirement a bit further, let me explain what it is used for: We are implementing a system that changes webcontent based on a remote SOAP service (i.e. customer database) and we want to never wait more than - say - 250ms for this to complete. Currently the best I can do is 1 sec connection timeout (in SoapClient() using the connection_timeout parameter) and 1 sec socket-read timeout (using ini_set() on the default_socket_timeout parameter). Assuming the remote SOAP server is down or slow, every pagerender with the SOAP request in it would get delayed by at least 1 sec, which is unacceptable in our case. BTW, comparing the PHP situation with other SOAP implementations, we have typically millisecond timeouts available: - Java (apachesoap): milliseconds - Java (axis): milliseconds - .NET: milliseconds - perl (SOAP::Lite): seconds Currently all socket/connection timeouts in PHP are implemented with second resolution. This is an unnecessary limitation in my view and I would love for this to be changed in mainstream PHP. I believe the effort to do so is minimal and has no impact to the users. The timeout numbers are usually used to populate a "tv" struct - in the current PHP code only the tv.tv_sec is typically set. So the change would simply be to promote default_socket_timeout (and similar variables) to a float and use the fractional part to properly populate tv.tv_usec with a microsecond number. In fact I found locations where the default_socket_timeout parameter is assumed to be a float (ext/standard/fsock.c - line 66). Also this simple code shows the local default_socket_context to accept a float parameter: <?php ini_set("default_socket_timeout",0.5); phpinfo(); ?> while ext/standard/file.h - line 113 stores it as a long. So a quick review of how this parameter is used throughout the code might be a-good-thing (TM) anyhow. An example implementation of the new, float resulution timeout use for the SoapClient/SoapServer is a few lines in ext/soap/soap.c and ext/soap/php_http.c as follows: soap.c
               if (zend_hash_find(ht, "connection_timeout", sizeof("connection
                   Z_TYPE_PP(tmp) == IS_DOUBLE && Z_DVAL_PP(tmp) > 0.0) {
                       add_property_double(this_ptr, "_connection_timeout", Z_
               }
php_http.c
       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_connection_timeout", sizeof
           Z_TYPE_PP(tmp) == IS_DOUBLE && Z_DVAL_PP(tmp) > 0.0) {
         tv.tv_sec = floor(Z_DVAL_PP(tmp));
         tv.tv_usec = (1000000.0*(Z_DVAL_PP(tmp)-floor(Z_DVAL_PP(tmp))));
         timeout = &tv;
       }
Similarly changes in the main PHP code could look something like this (assuming the var is a float): main/streams/transport.c default_timeout.tv_sec = floor(FG(default_socket_timeout)); default_timeout.tv_usec = (1000000.0 * (FG(default_socket_timeout)-floor(FG(default_socket_timeout))) ); The files that need to be changed are limited. grep -c default_socket_timeout ind . -name "*.[ch]" | grep -v :0 gives ./ext/imap/php_imap.c:4 ./ext/standard/file.c:1 ./ext/standard/file.h:1 ./ext/standard/fsock.c:1 ./ext/standard/streamsfuncs.c:2 ./ext/openssl/xp_ssl.c:2 ./main/streams/transports.c:2 ./main/streams/xp_socket.c:3 ./main/network.c:2 grep -c default_socket_timeout ind . -name "*.[ch]" | grep -v :0 gives ./ext/ftp/ftp.c:2 ./ext/curl/streams.c:1 ./ext/soap/php_http.c:1 ./ext/session/session.c:3 ./ext/sockets/sockets.c:5 ./ext/standard/uniqid.c:1 ./ext/standard/lcg.c:1 ./ext/standard/fsock.c:1 ./ext/standard/streamsfuncs.c:4 ./ext/openssl/xp_ssl.c:2 ./main/streams/xp_socket.c:2 ./main/network.c:2 Best regards Andreas

« previous php.internals (#21302) next »