The idea of using Pub/Sub leads me to the following question: when are LiveView components able to receive messages? My underlying concern is: what is the cost of using PubSub for an application having a large number of LiveViews/Components. Here are my specific questions:
- If a user of the website visits some route leading to the LiveView MyApp.LiveModule1.Index and this LiveView publishes a state-related message that will be needed by other LiveViews (for example the current user). Then, and only then, the user visits one of these other LiveViews for the first time: will the LiveView already exist and have processed the state-related message, or will it only start processing messages after being loaded at least once.
- If the answer to the previous question is that all LiveViews will receive the message without first needing to be explicitly loaded by the router, then isn’t it an issue for large scale applications having hundreds or thousands of LiveViews/Components? (such as the one we are considering building using Phoenix LiveView). Especially when message handlers are meant to immediately assign the state passed through the message (and thus claim memory). This could result in huge amounts of RAM memory being wasted, especially as the number of users grow. On the other hand, if LiveViews will not receive messages before being visited at least once before, then pub/sub is not suitable to manage global state (damn if you do, damn if you don’t sort of).
This state passing/sharing issue across components could end up being a deal breaker for us. Because apart from Pub/Sub, I do not like at all a lot of the solutions I’ve seen discussed in this thread that look very much like the fat controllers and other God-objects produced by junior object-oriented developers. I expected Elixir, Phoenix and functional programming in general to make composition clean and easy (which I feel is the case, expect for this specific problem). I am a bit worried to see that there does not seem to exist a mature solution to this problem, especially since as newcomers to Elixir we we would not have the skills and confidence required to pull out, evolve and maintain arcane clever tricks.
From this perspective, Pub/Sub would be the ideal option for us, but I have the scalability concerns I just mentioned. Maybe the answer to this simply is that processes are very lightweight in elixir so this is not an issue in practice? However this doesn’t address the fact a user of the website would claim memory in hundreds of LiveViews/Components that he may never visit during his session. The only solution I can see to this would be to manually check if the user has visited the LiveView before assigning state but my guts tell me that this may end up being quite messy to maintain (and what about checking this for non-routable LiveViews/components).
Generally speaking, having to worry about this seems to defeat one of the main benefits of composition: every component is focused on its own simple concerns so that complex solutions are built from simple parts. But if every component now has to worry about application infrastructure concerns, this does not inspire confidence in terms of the maintainability of complex systems.
I hope someone can ease these concerns because apart from that Phoenix LiveView is absolutely ideal and exciting for us, whether it is from a performance perspective, or from an Intellectual Property protection perspective. But the need to have shared state is so crucial in UI design that it would be reckless for me to bet our luck on LiveView for such an important project if there is no efficient and elegant solution to this problem, this would be like putting a time-bomb at the foundation of our project.
I used this occasion to contribute the apprehensions and thought process of an experienced teams mainly working in OOP ecosystems and looking at Elixir and Phoenix, since I believe an increasingly number of teams will start considering Phoenix and Elixir for their front-end moving forward, so hopefully this feedback can be useful to you.