danlucraft

danlucraft

“Woe unto you for using a Websocket” < interesting post, any takes from the Phoenix community?

I found this post very interesting and pretty convincing! It’s got me wondering about the advisability of building my next app using sockets for server sync.

https://www.adama-platform.com/2021/12/22/woe.html

I’m wondering what the perspective of the Phoenix community is on this? Concerns valid? Does Elixir/Phoenix have any particular advantages on these areas?

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Hey @danlucraft, at least in my reading the majority (although not all) of this post boils down to: “It’s different than stateless request response, and your programming language / stack may not support that well”. Specifically:

Problem: The world is dominated by request-response
Problem: Messaging stacks come with pain
Problem: Your socket will last a while; you need to think about time differently.
Problem: This creates a hard programming model
Problem: This is not PHP land

These are all variations on that theme, and that isn’t really a theme that’s all that relevant to Elixir. Elixir has stateful processes built in and a bunch of tooling to help make that ergonomic. In short, Elixir is already different and already presents a different programming model, it is already not PHP.

Problem: Don’t count on stickiness

Phoenix doesn’t.

Problem: Growing pains

Phoenix scales quite well.

Problem: The cattle behind the proxy

This is a legitimate concern, although depending on where you deploy your orchestrators may already have incremental draining. If not, that was just added to Phoenix.

Conclusions

I think overall perhaps the author has in mind a different use of websockets than Phoenix promotes (LiveView). I also think that the author’s critiques blend concerns introduced by the idea of messaging and state with concerns specific to websockets. That is to say, packet loss happens to HTTP requests too, and if you’re using those HTTP requests to transmit messages to a client then you’ll still need to think about idempotency, “at least once” semantics and so forth.

That isn’t to say there aren’t areas that I think could mature more as time goes on. LiveView doesn’t really offer a built in way to do deployments that change the user front end in a breaking way. But on the whole though the process management tooling you get with Elixir / Erlang gives you a lot of tools and certainly a lot of patterns to address this and other isssues.

21
Post #2
josevalim

josevalim

Creator of Elixir

I agree with the pendulum in general but - in this case - I believe React and Phoenix LiveView have innovated enough for this swing to be considerably different.

My first interactive server-side application was built in Rails, back in 2007-2008, using RJS, which was a Ruby to JavaScript. At the time, people were very critical of Ruby to JavaScript, focusing mostly on how limited having Ruby generate JavaScript was. Then we started emitting chunks of jQuery from the server.

The issue is that you mostly ended-up with a “spooky action at distance” application. First you rendered the page, then if the user pressed an action, you had to go and say “find this ID on the page and do X to it”. In other words, I had to write how to patch the page.

As your application grew, it was hard to keep those different parts in sync. Sometimes the ID structure would change. Sometimes the styles would differ. Sometimes it would even surface silly issues: a page rendered with 0 items was different than the same page rendered with 1 item which was then deleted. In general, it was hard to reason how my page would look like after 5 spooky actions.

Since this was brittle, developers would lose confidence in the codebase, leading them to adopt more and more browser-testing frameworks, which would increase CI times (often to 1h+), and hurt developer productivity, going into a vicious cycle. I saw this happening so many times and the lack of answers in this space was pretty much what shut me away from web development back then.

The JavaScript community was going through similar troubles and the React approach became the canonical answer to this problem: instead of the developer telling how the page should be patched, the developer change the state, render the page again, and the framework will compute the patch. This is a great programming model because all you need to do is: change the state. A page rendered with 0 items goes through the exact same process as a page rendered with 1 item which is then deleted.

There are several variations of the React model in how they generate the patch but the concept behind them is the same: the developer change the state and the framework compute the patch from that.

Now - I don’t know enough GUI development to say for certain if this approach existed - but AFAIK LiveView was the first to apply this concept at the web server level. Furthermore, it does not only implement the “render it again” idea, but it does so efficiently by computing minimal patches. And there are two important reasons for this:

  1. The Erlang VM. As others mentioned in this thread, efficiently generating a patch, requires a stateful connections (which for web means WebSockets) and being able to manage them at scale

  2. Elixir and functional programming. It is easier to compute patches and know what to send to the server if your data structures are immutable (in fact, LiveView approach is closer to Svelte in the sense we compute the patch from the template rather than comparing DOMs)

So, while there is a resurgence in server-side rendering, I don’t believe they are all equivalent. Some are still based on the flawed “the developer is patching the page”, others implement the “render it again” but without patches (they always submit the whole page on every interaction which causes a huge impact on latency and UX), and very few - pioneered by LiveView - do both “render it again + minimal patches”.

12
Post #9
josevalim

josevalim

Creator of Elixir

LiveView is used for interactivity and reactivity - but usually not for keeping persistent state. If you need something to exist once the user reloads the page, you must store it in the database.

So to answer your first two questions: they both are handled in the same way. Once you deploy or reconnect due to a crash, you fetch the necessary state from the database and continue from where you were. Also check this guide: phoenix_live_view/guides/server/deployments.md at v0.18.18 · phoenixframework/phoenix_live_view · GitHub :slight_smile:

Where Next?

Popular in Discussions Top

Donovan
Hello everyone, I’m so glad to have discovered this awesome community. Thanks for creating it! This is my second post, and apologies for...
New
thojanssens1
It would be nice to be able to define a redirect from one route to another from the router.ex file. E.g.: redirect "/", UserController, ...
New
eteeselink
Hi all, In the last days, two things happened: A blog post titled “They might never tell you it’s broken” made the rounds. It’s about ...
New
ben-pr-p
In general I’ve been sticking to this community style guide GitHub - christopheradams/elixir_style_guide: A community driven style guide ...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
pdgonzalez872
If this has been asked here before, please point me to where it was asked as I didn’t find it when I searched the forum. Maybe a mailing ...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
Fl4m3Ph03n1x
Background A few days ago I was listening to The future of Elixir from Elixir Talks, with Dave Thomas (@pragdave ) and Brian Mitchell. I...
New
jesse
Hi everyone, I hesitated to post this here because I don’t want you to think I’m spamming, but I’ve been working on a Platform-as-a-Serv...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43657 311
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement