skip to Main Content

I have a script that relies on a curl response from a remote server. On my current shared hosting, this takes around 300 ms for the response to arrive. I’m in the middle of a migration to VPS in a more suitable location so I expect the delay to drop significantly, but still not negligibly since the server is being built to act as an API, serving high amount of clients.

As of now, if I understand the mechanism correctly, those 300 ms waiting for a response, are 300 ms the server could be serving other requests. With the rest of the script taking only 3 ms to complete, this is potential 100 requests that couldn’t be served. Less, after the migration, but every such request will block high amount of potential requests that could be served while the script was merely waiting for the response.

So my question is, is there a way to suspend the script until the response arrives, making the process manager available to serve other requests in the meantime?

I only found out about sleep() and usleep() which is of no use to me, because I will never know how long it takes for the response to arrive.

2

Answers


  1. The keyword you’re looking for is async (Asynchronous) functionality which is available in PHP but with a small detour. With this, you dont need to wait or sleep it does so automatically without consuming your CPU cycles but not as effectively as other langauges as this is achieved in house as in, just another software layer.

    PHP is build on http, 1 request 1 fast answer. The more the ping, the longer it takes and this is quickly noticeable high volume scenarios but back then we didn’t have 64 core CPU’s back than.

    Each language has their own strenghts and in this explicit example you will find that its much more difficult to do this in PHP than other languages.

    If you’re only polling to an API, might I suggest Node instead? It has that functionality build in.

    Login or Signup to reply.
  2. As of now, if I understand the mechanism correctly, those 300 ms waiting for a response, are 300 ms the server could be serving other requests.

    This isn’t quite true. There are 300ms where that thread cannot process another request, but the server itself will be running many threads. This is parallel concurrency.

    In fact, it will be running many more threads than it has CPU cores, and actually relying on delays such as this to efficiently schedule them. It’s not unusual to have 100 active server threads on a server with 2 or 4 cores; at any given moment, at least 96 of those can’t use the CPU, but that’s generally fine because they’re waiting for other things.

    This only becomes a problem when every request has such significant waits that all the server’s threads are waiting at the same time. For instance, if you get 1 request per millisecond which all need this slow response, and set a limit of 100 threads, then after 100 ms all the threads will be waiting, and your CPU will be idle for 200 ms until the first one wakes up.

    The alternative approach is asynchronous concurrency. In that approach, the application itself manages a queue of events, and can start handling a new incoming request while it waits for the slow response.

    A popular example of this approach is node.js. Commonly, you would run one node.js thread per CPU core, and that thread would be responsible for handling as many requests "at once" as possible.

    There are a number of frameworks that allow this approach with PHP, such as ReactPHP, AmPHP, and OpenSwoole. Depending on how you’ve written your code, you may need to make substantial changes for it to work correctly, so would need to consider how much benefit you expect in practice.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search