How would one go about implementing a replaceable backend (or basically any part or module) so that it can be replaced at configuration/deploy time in Elixir?
My specific situation is a simple web app (in this case using Phoenix but I'm guessing this question applies to other situations as well) where I have a very simple backend using Agent
to keep state but I see a need in the future for being able to switch out the backend more or less dynamically.
I'm guessing both Ecto and Logger do this to some degree but being new to Elixir it's hard to know where to look.
This can be handled through an argument to the supervisor. For example, Ecto's backend supervisor takes an argument called
adapter
to specify which kind of database should be used:You could do the same in your application, probably a single argument to
start_link
will be enough – let's call itbackend
Now, you can of course set that argument dynamically when you spin up your application, based on a configuration file:
Now, the only piece that is missing is how to get the backend from a configuration file. There's no single answer to that because there are multiple ways of doing this.
Mix Configuration
You can simply use the existing Mix configuration, but it has the downside that you need to recompile the application every time the configuration changes:
Then adjust your application to read in the specified backend:
Roll your own
You could also implement your own config file. I am not going into detail here, but this is the rough idea:
String.to_existing_atom("Elixir.#{module_name}")
def backend
functionUse an existing run-time configuration library
Basically a glorified version of the previous solution. Googling around a bit I found a library called Conform. It looks interesting but I can'T make any promises because I've never used it myself.