Module definition at runtime: best practices

A couple of weeks ago the Discord team published an interesting article on how they built their systems on Elixir to serve up to 5 million concurrent clients.

In there they mention a number of libraries they’ve created to deal with a series of problems. One of these, fastglobal, seems to solve a problem I’ve been struggling with since I’ve started my journey in Elixir: the lack of a simple and performant memoization technique.

The TL;DR is that it acts as a global key-value store. For each stored key, it dynamically defines and compiles a simple module and function that return its value. This appears to be much faster than an ETS lookup (e.g. from Application.get_env/3). This technique was originally popularized by mochiglobal.

This seems like an interesting approach, so I’ve started digging and I’ve realized that Elixir has:

After a couple of tests it seems possible to build something very similar with these first-party APIs.

My questions are: is it considered a good practice? Are there other ways to deal with the problem? Would it make sense to add some first class module to the standard library to memoize values with great performance? (where “great performance” means “faster reads than ETS”).

Probably, since there are several projects (all claim to have great performance), which try to utilize this technique. The most recent that I’ve seen is probably buoy where :erl_syntax and :code are used to transform a read-only ets table into a module at runtime.

1 Like