3 ms·
Here's an analogy that I've been using lately that talks about why I love elixir. When I wrote apps in other languages in the past, I felt like I was building
by sb8244 4y ago
Here's an analogy that I've been using lately that talks about why I love elixir.
When I wrote apps in other languages in the past, I felt like I was building a big skyscraper. Everything was sorta connected and it was difficult to add new doors into the project. I was sometimes limited to building something I wanted because the runtime just wouldn't allow it.
When I'm writing Elixir, it's like I'm building a city. Everything works in concert, but I could build a small building next to a skyscraper next to another building.
This is because of the runtime, not the language. It's easy to build self contained "apps" that are deployed with everything else but isolated. It let's me build the app I want rather than forcing me into a very specific way of building.
And just to be clear I'm not talking microservice, that would be like building multiple cities connected only by little roads.
I'm work shopping this analogy since it's not as clear and concise as I'd like :)
PS. I'm pretty active in the community and other private communities and didn't know about the survey. I would have a hard time imagining large scale survey orchestration given that.
- dfee 4y agoThe analogy makes sense if you’re implying that it’s a monodeploy of apps - all on the same “plot of land”. I’ve never used the language, so no feedback to the value of the claim, but that metaphor does resonate.
- klabb3 4y agoMy experience using channels in Go, was that I replicated state across "actors", similar to microservices (which is one of many problems that microservices have vs a monolith). Worse, this state is not in sync, so you end up worrying a lot about logical race conditions (if you're paranoid like me). I ended up still using channels, but a single message bus with a single threaded dispatch loop. I am curious about if redundant state and state synchronization tends to be an issue in medium-to-large Elixir apps? If not, how does one design the component/actor hierarchy to avoid such issues?
- sieabah 4y agoWell each process has its own state, so if you needed to sync that you'd be storing it in mnesia, ets, or an external DB. Processes can watch and get messages about other processes if something were to succeed/fail.
- sb8244 4y agoI've worked on a variety of different size apps, but I haven't run into many issues with state synchronization yet. Generally, I try to keep data as close to its source of truth as I can. So if I need to synchronize state between actors, it would be to achieve a task and not to have duplicated data. This could be an artifact of how I build systems. I have heard of some people that build really small actors and do a lot of data exchange. Without knowing details, I'd lean towards that being an anti-pattern.
- throwawaymaths 4y agoYou tend to not write concurrency in elixir. You tend to borrow concurrency from your libraries and frameworks, which usually are fairly buttoned down. Most websites are basically stateless data fetch/transformation agents, and even the stateful ones are usually one process. Why muck around with all that when your framework does the right thing for you out of the box?
- bostonvaulter2 4y agoI'm not super familiar with channels in Go, but one way to avoid the need to synchronize state in Elixir is to use ETS (Erlang Term Storage) which is a way to store data (terms) in memory. If the state is in ETS than (optionally) any process on the node can read the state. Often this is paired with a single process that is allowed to update the state so that the state is always updated atomically. Often this pattern means that you don't need to distribute the same state to multiple processes, because instead they can just read the state they need from ETS (which is pretty fast/cheap).
- toast0 4y agoSo in Erlang (and I assume Elixir), the idiom is that the Process (Actor) holds the state. If you want to change the state, you send the Process a message, if you want to find out something about the state, you send the Process a message. You shouldn't be keeping the same state in multiple processes, because of all the problems you mention. Sometimes you have requirements where it's hard to assign any given piece of state to a single actor though, that's going to be challenging in any language. An ETS table (the OTP in-memory key/value database, more or less) is isomorphic with a Process that holds the data, although the reality is different. Mnesia if everything is done with transactions might be as well, although where I used mnesia, we did not use transactions and it was helpful to understand how the data flows between mnesia nodes, and when you might read outdated data.