Skip to content
Jan Sorgalla edited this page Aug 25, 2017 · 14 revisions

How can I use blocking functions?

The short version is: You can't.

ReactPHP is based on non-blocking I/O. Since PHP is single-threaded, that means that you cannot make any blocking calls without blocking the entire process. Which means that if you have 1K concurrent users, if each one blocks for just one millisecond, it will block the entire process for a whole second.

What are blocking functions? Pretty much any existing PHP code that touches the filesystem or the network. This includes, but is not limited to:

  • sleep
  • file_get_contents
  • file_put_contents
  • mkdir
  • fsockopen
  • PDO
  • mysql_*
  • etc.

If you need to use blocking calls, move them to a separate process and use inter-process communication.

How can I use ReactPHP with my web framework?

There's two answers to this question.

The first one is: You can't, because it makes blocking calls.

The second one is: You shouldn't. ReactPHP is made for long-running scripts. Network daemons. Programs that need to handle lots of concurrent connections and stream data incrementally. Traditional synchronous PHP stacks are good at what they do. Share-nothing horizontally scalable architecture, short-lived scripts that serve small pages, then go away. Your web framework is made for websites, and websites are best served by something like nginx+fcgi or similar.

So don't try to waste your time making it work with ReactPHP.

How do I communicate between processes?

Why should I do this?

  • Blocking calls: If you rely on something that does blocking calls, you can have a pool of workers that handle them. You need the workers to talk to the main daemon process.

  • Multiple servers: If you have more than one server, and your application is stateful, you need to synchronize the changes between them.

  • Sync + async stack: In many cases you will be running an async daemon alongside a traditional web stack. You may want to send messages from sync to async. For example: PHP behind nginx accepts a web request, sends a message to ratchet, ratchet broadcasts to all connected peers.

All of these use cases need the same thing: Inter-process communication. There's a couple supported of ways of doing IPC, that integrate with the event loop:

  • React/ZMQ: Builds on the ZMQ messaging library.
  • React/Stomp: Allows you to connect to a message broker, such as RabbitMQ or Apollo.
  • DNode-PHP: RPC protocol with implementations in many languages.
  • Predis/Async: Async driver for redis, which can be used for pub/sub or as a message queue.

What about threads?

No

PHP usually runs in a single-threaded environment. The engine is generally capable of multithreading, but not many SAPIs actually take advantage of that. In addition, there is the pthreads extension that exposes threads to PHP users.

If you are I/O bound, you don't need threads. ReactPHP gives you async I/O in a single process. Even though there is a single thread of execution, the I/O is concurrent.

Multithreading is a common strategy to increase the performance in CPU bound programs. Research aimed at leveraging threads is underway, but it is out of the scope of this document. Learn how multithreading works before you use it. And READ THIS.

Spawning a thread per connection is not a scalable strategy. A possible candidate pattern to implement pthreads in ReactPHP can be seen here:

Threaded Reactor