{"id":4454,"date":"2015-04-10T09:00:54","date_gmt":"2015-04-10T12:00:54","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=4454"},"modified":"2015-06-01T11:23:33","modified_gmt":"2015-06-01T14:23:33","slug":"build-embedded-and-start-permanent-in-elixir-1-0-4","status":"publish","type":"post","link":"http:\/\/blog.plataformatec.com.br\/2015\/04\/build-embedded-and-start-permanent-in-elixir-1-0-4\/","title":{"rendered":"Build embedded and start permanent in Elixir 1.0.4"},"content":{"rendered":"

Elixir v1.0.4 ships with two new important options for new projects. If you generate a new application with mix new<\/code>, you will see in your mix.exs<\/code>:<\/p>\n

[build_embedded: Mix.env == :prod,\n start_permanent: Mix.env == :prod]\n<\/code><\/pre>\n

Although those options were originally meant to be in Elixir v1.1, we have decided to bring them into v1.0.4 and do a new release. In this post, we will explain why.<\/p>\n

Protocol consolidation<\/h2>\n

One of Elixir’s most important features are protocols<\/a>. Protocols allow developers to write code that accept any data type, dispatching to the appropriate implementation of the protocol at runtime. For example:<\/p>\n

defprotocol JSON do\n  def encode(data)\nend\n\ndefimpl JSON, for: List do\n  def encode(list) do\n    # ...\n  end\nend\n<\/code><\/pre>\n

We have written about protocols before<\/a> and I recently explored on my Erlang Factory talk the foundation protocols have allowed us to build<\/a>.<\/p>\n

However, in order to play nicely with the dynamic nature of the Erlang VM where modules can be loaded at any time by the VM, as well as any protocol implementation, protocols need to check on every dispatch if a new implementation is available for any given data type.<\/p>\n

While we would gladly pay this price in development as it gives developers flexibility, we would like to avoid such in production as deployments gives us a consolidated view of all modules in the system allowing us to skip those runtime checks. For this reason, Elixir provides a feature called protocol consolidation, that consolidates all protocols with their implementations, giving protocols a fast dispatch to use in production.<\/p>\n

Prior to Elixir v1.0.4, protocol consolidation had to be manually invoked by calling mix compile.protocols<\/code>, which would consolidate protocols into a predefined directory, and this directory had to be explicitly added to your load path when starting your project. Due to the manual nature of such commands, a lot of developers ended-up not running them in production, or were often confused when doing so.<\/p>\n

For this reason, Elixir v1.0.4 introduces a :consolidate_protocols<\/code> option to your projects which will take care of consolidating and loading all protocols before your application starts. This option is also set to true when :build_embedded<\/code> is true.<\/p>\n

Build embedded<\/h2>\n

When compiling your projects, Elixir will place all compiled artifacts into the _build<\/code> directory:<\/p>\n

_build\/\n  dev\/\n    lib\/\n      your_app\/\n        ebin\/\n        priv\/\n      dep1\/\n      dep2\/\n  test\/\n  prod\/\n<\/code><\/pre>\n

Many of those applications and dependencies have artifacts in their source that are required during runtime. Such artifacts are placed in the priv<\/code> directory in Elixir applications. By default, Elixir will symlink to their source directories during development.<\/p>\n

In production, though, we could copy those contents to avoid symlink traversal, embedding<\/em> all relevant files to run your application into the _build<\/code> directory, without a need for their sources.<\/p>\n

That’s what the :build_embedded<\/code> option does and it defaults to true in production for new applications.<\/p>\n

Start permanent<\/h2>\n

Elixir code is packaged into applications. For example, each entry we saw under _build\/dev\/lib<\/code> above is a different application. When an application is started, it can be started in one of the three following modes:<\/p>\n