ETS Cache Invalidation on Module Reload in Elixir Mix Projects
0 reputation · 13 Jun 2021, 07:12 UTC
0 reputation · 13 Jun 2021, 07:12 UTC
Goal: keep cached data consistent after a module is recompiled during development.
Constraint: Elixir’s :ets tables (and libraries that wrap them) retain entries until explicitly deleted; Mix code reload does not trigger automatic flush.
Uncertainty: whether a configuration option or library hook can be enabled to automatically clear or recreate the cache when a module changes.
Specific questions:
34775 reputation · 13 Jun 2021, 19:10 UTC
There is no native Mix or Elixir configuration setting that automatically flushes :ets tables upon module reload. Because ETS tables are managed by the Erlang VM independently of the Elixir module lifecycle, they persist across recompilations unless explicitly cleared or deleted.
To keep cached data consistent during development, you must hook into the module lifecycle or process restarts.
The most direct way to clear a cache when a specific module changes is to use the __load__/1 function within that module. This function is executed every time the module is reloaded by the beam.
nmodule MyCache do
def __load__(__) do
if ets.table_exists?(:my_cache) do
ets.delete_all(:my_cache)
end
end
def init_table do
ets.new(:my_cache, [:set, :write_concurrency])
end
Cachex does not provide a built-in :on_load hook to automatically invalidate its backing ETS store. However, you can achieve this by wrapping your Cachex initialization in a GenServer. Since Mix reloads typically restart the application or specific supervisors in development mode, the GenServer's init/1 will run again, recreating the cache.
If you need to clear caches without adding logic to your business modules, you can use a custom Mix task in your mix.exs file. This is useful for global caches but introduces a slight overhead as it runs on every compilation cycle.
# In mix.exs
defp compile(_env) do
Mix.Tasks.run("cachex.clear", []) # Or your custom task
Mix.Tasks.run("compile", [])
super
end
This solution assumes you are using standard Mix development workflows where mix compile or hot code reloading triggers module reloads. If you are using a custom build system that does not trigger standard Elixir reloads, __load__/1 may not fire as expected.
It is uncertain whether specific third-party libraries wrapping ETS (beyond Cachex) have hidden internal hooks for invalidation; therefore, manual invalidation via the __load__/1 pattern is the most reliable method.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.