{"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 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 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 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 For this reason, Elixir v1.0.4 introduces a When compiling your projects, Elixir will place all compiled artifacts into the Many of those applications and dependencies have artifacts in their source that are required during runtime. Such artifacts are placed in the In production, though, we could copy those contents to avoid symlink traversal, embedding<\/em> all relevant files to run your application into the That’s what the Elixir code is packaged into applications. For example, each entry we saw under The default mode is temporary, which again, makes sense for development. For example, our test library called ExUnit, is also an application. If the application being tested crashes, we still want the ExUnit application to continue running in order to finish all tests and generate the proper reports. In this case, you definitely do not want your application to run as permanent.<\/p>\n However, in production, once your application crashes permanently, beyond recovery, we want the whole node to terminate, otherwise whatever you have monitoring your application at the operating system level won’t notice any change.<\/p>\n The Those new options have been introduced into Elixir v1.0.4 because they are very important for running Elixir in production. They bring more performance and stability to your Elixir-based systems.<\/p>\n There are other smaller changes in this release, like support for Erlang 17.5 and 18.0-rc1, as well as bug fixes. Check the release notes<\/a> for more information and enjoy!<\/p>\n <\/a><\/p>\n","protected":false},"excerpt":{"rendered":" Elixir v1.0.4 ships with two new important options for new projects. If you generate a new application with mix new, you will see in your mix.exs: [build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod] Although those options were originally meant to be in Elixir v1.1, we have decided to bring them into v1.0.4 and do … \u00bb<\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[143,235,215],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4454"}],"collection":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=4454"}],"version-history":[{"count":15,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4454\/revisions"}],"predecessor-version":[{"id":4701,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4454\/revisions\/4701"}],"wp:attachment":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=4454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=4454"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=4454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}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
Protocol consolidation<\/h2>\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
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
: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
_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
priv<\/code> directory in Elixir applications. By default, Elixir will symlink to their source directories during development.<\/p>\n
_build<\/code> directory, without a need for their sources.<\/p>\n
:build_embedded<\/code> option does and it defaults to true in production for new applications.<\/p>\n
Start permanent<\/h2>\n
_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
\n
permanent<\/code> – if app terminates, all other applications and the entire node are also terminated<\/li>\n
transient<\/code> – if app terminates with :normal reason, it is reported but no other applications are terminated. If a transient application terminates abnormally, all other applications and the entire node are also terminated<\/li>\n
temporary<\/code> – if app terminates, it is reported but no other applications are terminated<\/li>\n<\/ul>\n
:start_permanent<\/code> option starts your application as
:permanent<\/code> and it defaults to true in production for new applications.<\/p>\n
Summing up<\/h2>\n