A library for using Fly.io's Multi-Region Databases with Ecto.
This library assumes that:
- You have an app hosted on Fly.io
- You've already created and configured read-replica databases on Fly. Refer to Fly.io's documentation for more information on how to do that.
It's likely that Fly will implement their own version of this library. So this library should serve as a proof-of-concept. There are a number of assumptions and improvements that could be made. Please use this library at your own risk and know that I never intended it to be used in production.
This library was based on what I originally implemented in this blog post
The package can be installed by adding fly_multi_region
to your list of dependencies in mix.exs
:
def deps do
[
{:fly_multi_region, "~> 0.0.1"}
]
end
If you're following the Fly.io guides then your database config will happen at runtime. Add the following to the runtime.exs
file:
config :fly_multi_region,
region: System.get_env("FLY_REGION"),
regions: ["nrt", "ord"],
url: System.get_env("DATABASE_URL"),
opts: [
socket_options: [:inet6],
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
]
Parameters:
- region: generated by Fly.io by default
- regions: a list of replicas in your cluster
- url: database url
- opts: configuration options for Ecto
Add FlyMultiRegion to your Application's supervision tree
As mentioned in Ecto's documentation for replica databases it's necessary to add any Repos to your supervision tree. With that in mind, make sure to add FlyMultiRegion
to your Application module (application.ex)
def start(_type, _args) do
children =
[
...,
FlyMultiRegion
]
...
Supervisor.start_link(children, opts)
end
Add use FlyMultiRegion.Repo
to your projects main Repo module:
defmodule MyApp.Repo
...
use FlyMultiRegion.Repo
end
When ever making a read request with ecto, use .replica()
Example:
# original
Repo.all(User)
# becomes
Repo.replica().all(User)
- tests
- make replica's more configurable (for example, the assume Postgres at the moment)
- remove Ecto as a dependancy (it's only used to parse a database url)