As an experiment I have tried to serve demo application using RoadRunner.
Here’s the pull request/branch you can try yourself.
Everything before while ($request = $psr7->acceptRequest()) {
runs only once and is kept in memory. That includes whole container state, application, setting error handler etc.
What is executed every request is actual PSR-7 request handling with middleware stack.
I had to adjust the way middleware dispatcher works because of state. Previously it was removing middleware from the stack. Now it is keeping a pointer that could be reset instead.
There is currently a problem with session with more than a single worker. Other than that it seems to work fine. Response times are amazingly good:
INFO[0001] ::1 {59.0ms} 200 GET http://localhost:8080/ <----- warmup
INFO[0002] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0003] ::1 {1.01ms} 200 GET http://localhost:8080/
INFO[0004] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0005] ::1 {4.00ms} 200 GET http://localhost:8080/login
INFO[0012] ::1 {1.052s} 302 POST http://localhost:8080/login <----- password hash computation
INFO[0012] ::1 {1.01ms} 200 GET http://localhost:8080/
INFO[0013] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0014] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0014] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0014] ::1 {1.01ms} 200 GET http://localhost:8080/
INFO[0015] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0015] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0015] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0016] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0016] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0017] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0017] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0018] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0018] ::1 {1.01ms} 200 GET http://localhost:8080/contact
INFO[0018] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0018] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0019] ::1 {1.01ms} 200 GET http://localhost:8080/
INFO[0019] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0020] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0020] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0020] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0021] ::1 {1.00ms} 200 GET http://localhost:8080/
INFO[0068] ::1 {0.99ms} 200 GET http://localhost:8080/
INFO[0069] ::1 {1.00ms} 200 GET http://localhost:8080/contact
INFO[0069] ::1 {2.00ms} 200 GET http://localhost:8080/