Build-time support for hot-code upgrades.
Forecastle
provides build-time support for the generation of releases that correctly support hot-code
upgrades. This includes:
Additionally, Forecastle
ships with a appup compiler and a mix task for relup generation.
Forecastle
is not intended to be taken as a direct dependency. Most applications should prefer to
take a dependency on Castle directly which will, in turn
take a build-time dependency on Forecastle
.
For projects that don't define a release, but use the appup
compiler, it's sufficient to
bring Castle
in as a build-time dependency:
def deps do
[
{:castle, "~> 0.3.0", runtime: false}
]
end
For projects that do define one or more releases, Castle
should be brought in
as a runtime dependency:
def deps do
[
{:castle, "~> 0.3.0"}
]
end
Forecastle
integrates into the steps of the release assembly process. It requires
that the Forecastle.pre_assemble/1
and Forecastle.post_assemble/1
functions are
placed around the :assemble
step, e.g.:
defp releases do
[
myapp: [
include_executables_for: [:unix],
steps: [&Forecastle.pre_assemble/1, :assemble, &Forecastle.post_assemble/1, :tar]
]
]
end
The following steps shape the release at build-time:
In the pre-assembly step:
Forecastle
will
do its own equivalent expansion into sys.config
prior to system start,
first with runtime.exs
(if it exists) and then with any Config Providers.Forecastle
and its
dependencies. This is used only during the aforementioned expansion.The system is then assembled under the :assemble
step as normal.
In the post-assembly step:
sys.config
generated from build-time configuration is copied to
build.config
.bin
folder is replaced with one that provides
additional commands to manage releases.runtime.exs
is copied into the version path of the release.releases
folder as name-vsn.rel.relup
file is copied into the version path of the release.You are responsible for writing the appup
scripts for your application, but Forecastle
will copy the appup into the ebin
folder
for you. The steps are as follows:
# You can call the file what you like, e.g. appup.exs,
{
'0.1.1', # Code is eval'd so can also: to_charlist(Mix.Project.config[:version]),
[
{'0.1.0', [
{:update, MyApp.Server, {:advanced, []}}
]}
],
[
{'0.1.0', [
{:update, MyApp.Server, {:advanced, []}}
]}
]
}
This file will typically be checked in to SCM.
:appup
compiler.
# Mix.exs
def project do
[
appup: "appup.exs", # Relative to the project root.
compilers: Mix.compilers() ++ [:appup]
]
end
Forecastle contains a mix task, forecastle.relup
, that simplifies the generation of
the relup file. Assuming you have two unpacked releases e.g. 0.1.0
and 0.1.1
and you wish to generate a relup between them:
> mix forecastle.relup --target myapp/releases/0.1.1/myapp --fromto myapp/releases/0.1.0/myapp
If the generated file is in the project root, it will be copied during post-assembly to the release.