ETS race condition?

This is not an anti-pattern in any way. It completely depends on what your use cases are and what your trying to achieve. Also, using an agent is just as a much of a bottleneck as using a GenServer, so this idea doesn’t improve anything.

No, it isn’t. Its very normal to have a GenServer start an ets table and serialize writes to that ets table, but allow the callers to read from the ets table directly. Its also normal to have a private ets table in a GenServer that only that GenServer can read from. If that GenServer needs to manage thousands of records, reads from an ets table will be much higher throughput then reads from, say, a map. In either case, there’s nothing inherently wrong with using ets tables inside of a process.

Ets tables are attached to the process that creates them. So if the creating process dies or is shutdown, the ets table is collected. By creating the table in the application supervisor, your essentially saying, “I want this table to live for as long as the application does”. That is not always correct. You may want to think about the life cycle of the table and create it and supervise it so that the table is cleaned up correctly.

As for your actual question, the main issue here is that your using cast instead of call. In this case putting an ets table inside of a GenServer might be the wrong approach. Maybe you don’t need an ets table or a GenServer or a cache at all. But I hope that you and others don’t assume that putting ets tables in processes is wrong, in general. Because its not.

12 Likes