How does Passenger deal with blocking I/O from applications if it is single threaded? Does the entire event loop block while doing I/O?
The other component is the Ruby application process. I believe you are talking about this component.
Concurrency on the Ruby application process side is handled using two strategies:
1. Multiprocessing. 1 process per concurrent connection, with a buffering layer. This is architecturally the same as how Unicorn works when behind an Nginx reverse proxy.
2. Multithreading. 1 thread per concurrent connection, possibly with multiple processes. This is architecturally similar to Puma, though not entirely the same. It should be noted that multithreading support is available in the Enterprise version only.