Hi. I’m new to the forum and to Elixir. I’ve been reading Elixir in Action (2nd Edition). I’m really enjoying it, but once the book got into advanced Supervisor trees, Registry, ETS tables, and clusters I began stretching to understand how and if I’d need to use these features of OTP.
I suppose I may at some point, but not have clear problem to solve with those features makes learning them a bit difficult.
I’m wondering how often do you guys reaching for those features while building apps in Elixir? I can see how GenServer and Supervisors (as well as Tasks) may be commonly used. But how often are other OTP features really called for?
Here’s what I use often and why:
- supervisor trees – because they help to control how the parts of the application start and stop (their order, restart strategies)
- registry – to be able to find “simple one for one” processes, “services”, sometimes as a local pubsub as well
- ets tables – as a cache or some other kind of datastore for ephemeral data, it’s fast and easy
Even without using OTP explicitly in your project, Erlang and Elixir are still insanely useful for their preemptive parallelism. Meaning even if your server is loaded every task is getting its time slice. Erlang and Elixir servers will lag under severe pressure – as will servers in any language – but they remain stable and responsive. Definitely not the case for servers written in many other languages – at least in my experience with 6+ others.
As for OTP itself, doing my own supervision trees to isolate limited or fragile external resources – like connection pools or error-prone 3rd party REST APIs – has proven invaluable in my Elixir projects, many times.
From my experience100% of all non-trivial applications use some features of OTP. Non trivial: RabbitMQ, Ejabberd, Tsung, CouchDB, LeoFS, Riak etc. I’m not including application libraries in this group.
Of the features: GenServer make up a good 90% of it. In many cases it would have been more prudent to use gen_fsm/gen_statem.
Note: you have to have an Application for a Supervisor to hang off from.
Clustering is extremely common either the classical active primary/passive secondary or load balance distributed.
I do not consider Registry, ETS tables as features of OTP.
In addition to these other answers I want to point out that if you’re using a framework like Phoenix then a lot of the OTP structure for typical web requests is already set up for you and you don’t need to mess with it for a long time.
And then in regards to supervision trees this is by far my favorite talk about a practical example of a supervision tree:
Is anyone using multicall/multicast in the wild by the way? (And if so, how?)
I expect that they are useful once you have nodes with completely different responsibilities connected in the same BEAM cluster, but I have not encountered such a situation myself yet so far.
Don’t fear not grokking OTP - you can absolutely build out an advanced complete app that gets the job done without directly using OTP (all your libraries Phoenix, Ecto, Cachex, EctoJob etc. etc. - will of course leverage OTP under the hood)
I have such an app in production, and I’m very happy with it - yes it could be more advanced, but simplicity also has it virtues.