A separate websocket server is a huge pain in any language. A great feature of Phoenix for Elixir is that the webserver and the websocket server are in the same process tree.
I'll try this new approach for Ruby and see how it scales.
I agree separate servers can be a pain, especially in a development environment. But I also believe separate servers can be a useful architecture in production, regardless of whether the web framework being used is thread-per-connection or event-driven.
Using separate servers can make it possible to upgrade/restart the backend process without necessarily disconnecting clients. It can allow managing/scaling the front tier separately from the back tier, which can make sense if you already do this for your request/response stuff (e.g. cache tier separately managed/scaled from web service tier). It's also a sane way to manage long-lived connections from a function backend like AWS Lambda, so the function doesn't have to run for the entire duration of a connection.
I created Pushpin (https://pushpin.org) to attempt to standardize this split-process architecture for all languages. It is a bit of a pain in a development environment, but a lot of fun in production. :)
You bring up a lot of important points none of which apply to Elixir/Phoenix. In Erlang/Elixir world you can even live upgrade a running system to a new release without restart.
Can you really live upgrade an Erlang process without disconnecting TCP connections it is using? If so that's really interesting, would be curious to learn more.
Yes, you don't actually restart the Erlang VM; it loads your new application code (byte code) and sends the next message/request it receives to the newly loaded module. The default state for any process is to be blocked on receiving a new message. Processes in the middle of an I/O operation for example, will get the new code after it finishes that operation and waits to receive its next message.
You have great points as far as application architecture is concerned.
However, as far as server architecture goes - even if we separate the application into two different processes (HTTP and WebSockets), the current situation is that the WebSocket server in Ruby will run two IO reactors / "servers" internally (unless you use a custom WebSocket enabled server such as iodine).
This post is more about the way WebSocket servers are implemented using Rack than about the question of application architecture.
It does have drawbacks, but having use crossbar.io for python/js/java/php, the benefit is huge if it abstract away the transport and gives you well crafted high level primitives such as routed rpc and pubsub out of the box.
Also, you can switch to microservices later for peanuts.
One of the reasons i really like Perl is Mojolicious. Thanks to it we don't need separate servers for websockets and HTTP anymore. https://mojolicious.org
It's the first time I hear about new web servers in Ruby after thin, passenger, unicorn, puma. Anyone has real life applications with Rails/Sinatra on iodine or agoo?
First time I hear about them, too. Googling Rails + Iodine doesn't yield much information. I'm going to try replacing Puma in one of my Rails apps. The benchmarks suggest that this could be a real win.
I'll try this new approach for Ruby and see how it scales.