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


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to