Some notes about Puma that I collected while moving Shipit to work with Puma.
- Shipit is using a gem called pubsubstub to handle sockets. That gem will force the app server connection to be alive as long as the socket is open.
- On the other side, Rails 5 introduced ActionCable that acts as a seperate process that uses EventMachine to handle sockets, thus after initiating the socket connection, the app server gets out of the picture. Unfortunatly, Shipit doesn't use ActionCable.
- Has no worker request timeout. There is a setting called worker_timeout, but that's not for request timeout. Suggested workaround is to set Rack timeout, or have Nginx infront of it.
- Won't restart gracefully if there are open connections(like managing sockets itself). Suggested workaround is to set the force_shutdown_after. However, that works per thread, and also reload happens sequentially. Thus, if a worker has 10 threads, and they have active connections like sockets and you set the
force_shutdown_after
to 30 secs, it will take 300 secs to turn off 1 worker only. Recommeded option is just to restart Puma workers forcefully, if they don't do gracefully withen a timeout of 60 seconds for example. - Shopify runs a seperate app server to serve the socket request
/events
. I originally went with that path of having a separated app server for sockets, then decided not to complicate things, and force restart after 60 seconds timeout.