Fl4m3Ph03n1x
Background
In the book “Elixir in Action” I remember reading somewhere that you should have ETS wrapped in a GenServer because this way the GenServer watches over the ETS and is able to restart it should something fail.
However, I have seen in another book the opposite. People just create ETS tables in the application.ex file together with the app supervisor:
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
children = [module.A, module.B]
:ets.new(:my_table, [:public, :named_table])
opts = [strategy: :one_for_one]
Supervisor.start_link(children, opts)
end
end
Question
Which approach is better? Isn’t it dangerous to put the ETS table at the app supervisor level (if the table crashes, the whole app follows right?)
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Hello,
I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter).
The diffic...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
Anyone here using Honeybadger?
My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of
Bandit.HTTPError...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Aludel - LLM Evaluation Workbench
Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
LostKobrakai
I’d think less about “if ETS fails” or “which approach is better”, but rather in terms of data locality and data consistency. A ETS table being e.g. a read-through cache for some external resource should be co-located to the process accessing the external resource. Maybe they should even restart together in certain scenarios to prevent stale data in the cache, but also because a root application process shouldn’t really be aware of implementation details of subsystems.
Whenever you’re asking yourself how to structure a supervision tree it’s about which things belong together and need to be restarted together to bring the system back to a known state while minimizing the amount of disruption to unrelated systems. I’d suggest watching @ferd’s talks or read his blogposts on the topic.
Fl4m3Ph03n1x
Links please
But if I am looking for overall failsafe recovery, like @sasajuric is, wouldn’t the second approach be more dangerous?
LostKobrakai
The parts in the middle of the talk are the most relevant, but I’d suggest watching the whole thing. There’s also a blogpost with the same title (and the others are good as well).
If you’re planing to crash ETS then yes, putting it in the root process is not the way to go, but take the argument with a grain of salt because if you’re crashing ETS I’d imagine it’s not the only thing going badly in the system.
sasajuric
This is the key insight here. By having a GenServer owner of an ETS table, and placing that owner in a proper place in the supervision tree, we can ensure the desired stop and restart behaviour on a case-by-case basis. In other words, it’s equally straightforward to ensure that the cache is purged on termination, as well as to ensure that the cached data lives on after the restart.
Occasionally, I find myself using a supervisor as the owner of a table, but more often I tend to have a dedicated GenServer for that purpose. I used to start tables during app start too, but I never do this anymore. The small convenience gain is not worth the confusion which comes this approach (e.g. the data lives on until the app is stopped, and it’s not clear from the code where the table is created and who owns it).
alexiss
Just in case - GenServer sometimes isn’t a best choise. Agents can be used too
peerreynders
The
GenServersimply acts as the owner process. When the owner process is killed by the supervisor the ETS table goes with it. Then the supervisor restarts theGenServerwhich in turn creates a fresh ETS table.How would a table crash??? Granted the contents can get corrupted which can lead to processes that rely on it to crash. If that can happen then it makes sense to run the owner process and client process under a
:one_for_allsupervisor which would also kill the owner process to create a fresh table.But there are other use cases where the ETS table acts as a backing store to bridge the termination of one process when it is replaced with a new one - in that case it makes sense to have the supervisor own the table (Don’t loose your ETS tables).
Article: The Hitchhiker’s Guide to the Unexpected