ecto_boot_migration v0.2.0 EctoBootMigration
Helper module that can be used to easily ensure that Ecto database was migrated before rest of the application was started.
Rationale
There are many strategies how to deal with this issue, e.g. see https://hexdocs.pm/distillery/guides/running_migrations.html
However, if you have any workers that are relying on the DB schema that are launched upon boot with some methods, such as release post_start hooks you can easily enter race condition. Application may crash as these workers will not find tables or columns they expect and it will happen sooner than the post_start hook script will send the commands to the the application process.
In stateless environments such as Docker it is just sometimes more convenient to perform migration upon boot. This is exactly what this library does.
Currently it works only with PostgreSQL databases but that will be easy to extend.
Usage
defmodule MyApp do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
{:ok, _} = EctoBootMigration.migrate(:my_app)
children = [
supervisor(MyApp.Endpoint, []),
worker(MyApp.Repo, []),
]
Supervisor.start_link(children, [strategy: :one_for_one, name: MyApp.Supervisor])
end
end
Credits
Inspired by https://github.com/bitwalker/distillery/blob/master/docs/Running%20Migrations.md
Link to this section Summary
Functions
this prevents pre-mature return that could cause the main app to exit, because the repos were not 100% shutdown
Tries to run migrations
Tries to run migrations
Start apps necessary for executing migrations
Start the Repo(s) for app, returns pids
Link to this section Functions
debug?()
loaded?(app)
log(msg)
log(msg, bool)
this prevents pre-mature return that could cause the main app to exit, because the repos were not 100% shutdown
migrate(app)
migrate(any()) ::
{:ok, :noop} | {:ok, {:migrated, [pos_integer()]}} | {:error, any()}
migrate(any()) :: {:ok, :noop} | {:ok, {:migrated, [pos_integer()]}} | {:error, any()}
Tries to run migrations.
Returns {:ok, {:migrated, list_of_migration_ids}} if any migrations have
happened.
Returns {:ok, :noop} if no migrations have happened.
Returns {:error, reason} if error occured.
migrated?(app)
Tries to run migrations.
Returns true if any migrations have happened.
Returns false if no migrations have happened.
Throws if error occured.
run_migrations(repos)
start_dependencies()
Start apps necessary for executing migrations
start_repos(repos)
Start the Repo(s) for app, returns pids