Remoting bottleneck: only two connections can be opened at a time

Posted on Saturday 26 March 2005

After writing yesterday’s post on batch calls I realized this might explain the weird issue that people have if a method is called that has a sleep() in it (simulating a very slow method). It seems that under certain conditions, if you call a remote method with a long sleep time, it will also slow down all subsequent remote method calls. It almost looks as if PHP is single-threaded. Now I know for a fact this is wrong, and the fact that batch calls are allowed in remoting might explain that as the server cannot send back any results if not all of the remote methods invoked have finished.

But Jesse Warden pointed out that even making sure that calls are not batched by waiting a frame or using setInterval between calls did not totally solve the sleep issue. So while the above explanation explains part of the issue it does not explain all of it. I did some tests myself and here is what I discovered:

The Flash player seems to accumulate the calls for a frame. The correct way to see this is adding a call to NetDebug::trace(”In method now”); in the invoked remote method. This will add a single trace header per request. So if you call 20 remote methods, and you see only one trace in the NetConnection debugger, there was only one call. If you call 20 remote methods, and see 20 trace actions in the NetConnection debugger, that means it was sent as separate calls. Any number between 1 and 20 traces means the call was split into several batches.

Now I tried with deferred (next frame) calls and while I saw several traces in the NetConnection debugger, it still showed the odd behaviour with sleep. So it seemed either that:

  1. The web server or PHP is single threaded (unlikely)
  2. The Flash player was waiting for a remote response before sending the next request (just as unlikely)

But in fact it’s none of the above. I verified this by doing packet sniffing using TCP Spy and multiple calls with sleep(1) in some methods and not in others. As it turns out Flash opens a limited number of connections; on my system, using the standalone version or the ActiveX in IE or the plugin in Firefox, it creates 2 connections.

That means that Flash has a limited number of channels to send data through. So if one is blocked, (for example by a sleep) and the other one is clear, data will continue to be passed in the clear channel. As soon as both channels are blocked it will seem as though Flash or Apache or PHP are single-threaded, when in fact it’s a question of number of open connections.

I wanted to test this theory by doing the following:

Create a service with two methods, one called method1 and another called method2. Method1 contains sleep(10) and method2 is empty. They return either 1 or 2 so we can easily see which returns before or after.

So I created a Flash file that would call method1 and then call method2 in a setInterval(200). In theory, every return from method2 should come before method1. On the other hand, if I would call method1 two times (separated by an interval to disable batch calls) before the method2 setInterval, it would, in theory, block both channels.

Now here is the caveat: the player in the IDE and the standalone/plugin/ActiveX players behave differently. In the IDE, it waits for both calls to come back before starting to send new ones, while in the standalone, as soon as one channel is free it starts a new request.

If you test the above in the standalone, it will work as expected, but not in the IDE.

While I was working with this, I noticed that when a connection is interrupted, the number of headers int is replaced by garbage, and it can severally crash AMFPHP and Apache if error_log is on, so I solved that issue (ie: it used to make the error log grow by 20 megs per AMFPHP call). So please download the new bleeding edge version for that issue now solved


WordPress database error: [Can't open file: 'wp_comments.MYD'. (errno: 145)]
SELECT * FROM wp_comments WHERE comment_post_ID = '64' AND comment_approved = '1' ORDER BY comment_date

No comments have been added to this post yet.

Leave a comment




Your e-mail address is never displayed. If you run into issues with SpamKarma blocking you, email me at $patrick->5etdemi(com)


RSS feed for comments on this post | TrackBack URI