# Change to timeout use

- Thread: https://externals.io/message/21302
- Original archive: https://news-web.php.net/php.internals/21302
- Started by Andreas Schiffler on 2005-12-21T15:49:56+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #21302 — Andreas Schiffler — 2005-12-21T15:49:56+00:00

URL: https://externals.io/message/21302#21302

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

---

## #21308 — Wez Furlong — 2005-12-21T19:20:19+00:00

URL: https://externals.io/message/21302#21308 · In reply to: #21302

There's not much difference between .25 and 1 second.
If you're talking soap on each page render, you're probably doing
something wrong anyway; you should have some kind of cache in your web
app.

That's not to say that we won't fix this issue, but we're not in a
rush to do so.
If you're feeling motivated, we'll gladly accept a patch against HEAD
that implements this; otherwise, you'll have to wait until someone is
motivated enough.

--Wez.


> 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

---

## #21309 — Andreas Schiffler — 2005-12-21T20:37:14+00:00

URL: https://externals.io/message/21302#21309 · In reply to: #21308

Wez,

>There's not much difference between .25 and 1 second.
>  
>
Ah, this may be so for the traditional use of webservices. But for 
eCommerce applications for example speed is king and its also very 
important to provide consistent speeds (i.e. not hang). I don't have 
published reference links on this, but some of our private documents 
point to a target of max. 200ms for an ad-serving related webservice 
(which is technically absolutely feasable anyhow, even across the country).

>If you're talking soap on each page render, you're probably doing
>something wrong anyway; you should have some kind of cache in your web
>app.
>
>  
>
No - by nature of our webapp, every request is unique and a cache would 
not help.

The PHP soap implementation is very fast by the way ... my benchmarks 
indicated 3-4ms request times on the LAN (without doing anything useful 
inside the request). This compares to over 30ms for the 
mod_perl/Soap::Lite implementation (and I haven't tested Java or .Net)

>That's not to say that we won't fix this issue, but we're not in a
>rush to do so.
>If you're feeling motivated, we'll gladly accept a patch against HEAD
>that implements this; otherwise, you'll have to wait until someone is
>motivated enough.
>
>  
>
OK. I understand that. I'll try my best to come up with a patch set then.
Can someone point me to some documentation on how to do this?  Is 
someone willing to assist me in making this patch?

Bye
Andreas

>--Wez.
>
>
>  
>
> > […]

---

## #21311 — steve — 2005-12-21T23:02:20+00:00

URL: https://externals.io/message/21302#21311 · In reply to: #21308

> There's not much difference between .25 and 1 second.

Actually, there is. It depends on the length of time of a typical page
request (and the proportion of the delay to the typical time), and the
hardware setup to handle that. The 4x slowdown can cause a cascade
effect as it might cause more than 4x simultaneous connections on the
target (causing it to slow down, and the problem to keep growing).
That gets amplified by the number of webservers a bit.

I don't use SOAP in such a way, but it is analogous to MySQL queries,
and having a 1s time for a common query can lead to all sorts of
problems.

The reason I'm chiming in here is to suggest that if this is looked
at, that it be made universal for all network timeouts. I'm thinking
MySQL in particular, as there could be a class of websites that don't
use custom connection pooling handlers on their webservers to get
around this (useful, for example, if switching to backup servers).

So maybe fractional seconds for network related timeouts could be a
wishlist item for PHP 6?

Personally, I wouldn't mind connection pooling too. I like to dream...

:)

---

## #21312 — Wez Furlong — 2005-12-21T23:03:59+00:00

URL: https://externals.io/message/21302#21312 · In reply to: #21309

> > […]
> Ah, this may be so for the traditional use of webservices. But for
> eCommerce applications for example speed is king and its also very
> important to provide consistent speeds (i.e. not hang). I don't have
> published reference links on this, but some of our private documents
> point to a target of max. 200ms for an ad-serving related webservice
> (which is technically absolutely feasable anyhow, even across the country).

OK, but this is in the case where you've got an error, right?
What do you do if you don't get a response, and how often does it happen?

> OK. I understand that. I'll try my best to come up with a patch set then.
> Can someone point me to some documentation on how to do this?  Is
> someone willing to assist me in making this patch?

It sounded like you'd identified all the places that needed adjusting;
just go ahead and try making it work :)
You can ask questions here on internals@ and I'm sure you'll get some
help if you ask the right questions (try to be as specific as possible
so it's easier to answer).

Hope that helps :)

--Wez.

---

## #21313 — Wez Furlong — 2005-12-21T23:08:43+00:00

URL: https://externals.io/message/21302#21313 · In reply to: #21311

The problem isn't the duration of the soap query call, it's how long
to wait before giving up on establishing the connection.  The connect
timeout is completely independent from the soap call duration or the
work that it performs.

--Wez.


> > […]
>
> Actually, there is. It depends on the length of time of a typical page
> request (and the proportion of the delay to the typical time), and the
> hardware setup to handle that. The 4x slowdown can cause a cascade
> effect as it might cause more than 4x simultaneous connections on the
> target (causing it to slow down, and the problem to keep growing).
> That gets amplified by the number of webservers a bit.
>
> I don't use SOAP in such a way, but it is analogous to MySQL queries,
> and having a 1s time for a common query can lead to all sorts of
> problems.
>
> The reason I'm chiming in here is to suggest that if this is looked
> at, that it be made universal for all network timeouts. I'm thinking
> MySQL in particular, as there could be a class of websites that don't
> use custom connection pooling handlers on their webservers to get
> around this (useful, for example, if switching to backup servers).
>
> So maybe fractional seconds for network related timeouts could be a
> wishlist item for PHP 6?
>
> Personally, I wouldn't mind connection pooling too. I like to dream...
>
> :)

---

## #21316 — Rasmus Lerdorf — 2005-12-22T02:21:08+00:00

URL: https://externals.io/message/21302#21316 · In reply to: #21311

steve wrote:

> Personally, I wouldn't mind connection pooling too. I like to dream...

And where would such a pool live?

---

## #21317 — Sebastian — 2005-12-22T04:30:48+00:00

URL: https://externals.io/message/21302#21317 · In reply to: #21309

> The PHP soap implementation is very fast by the way ... my benchmarks
> indicated 3-4ms request times on the LAN (without doing anything useful
> inside the request). This compares to over 30ms for the
> mod_perl/Soap::Lite implementation (and I haven't tested Java or .Net)

Can you provide code and related info about these benchmarks?

---

## #21319 — Andreas Schiffler — 2005-12-22T12:52:18+00:00

URL: https://externals.io/message/21302#21319 · In reply to: #21317

Sebastian wrote:

> > […]
>
>Can you provide code and related info about these benchmarks?
>
>  
>
http://www.ferzkopp.net/Software/SoapBench.zip
