My Favorite Pattern Without a Name

Written by Pete Corey on Jan 30, 2017.

My recent dives into Elixir have been changing how I write software. More and more I find myself writing in a functional style, even in languages where its not the norm.

As my style of programming changes, I find myself re-using patterns and ideas across many different languages.

This article is about one of the patterns I use most often; interestingly, a pattern without a clear name.

As my friend Dean Radcliffe pointed out, I'm probably describing a fluent interface as described by Martin Fowler. Today I learned.

An Example

I often find myself wanting to chain together many function calls, passing in the results of previous calls into the next function in the chain.

Sometimes, the next function in the chain only needs the result of the previous function. Sometimes, it needs the result of a function further back in the chain.

To make things more real, let’s consider an example. Imagine we’re building a system that receives and responds to text messages from users. In this example, we’ll have three functions:

def get_user(phone_number) do

def get_response(message) do

def send_response(user, response) do

The get_user function takes in the sender’s phone number and returns a corresponding user object. The get_response function takes in the sender’s text message and returns a response. send_response will take in a response and the user to send that response to.

One way of calling these three methods together might look like this:

user = get_user(sms.from)
response = get_response(sms.message)
send_response(user, response)

This is a fine solution. However, we’re binding user and response for no other reason than to pass them into send_response.

Additionally, if our methods evolve over time to need more inputs, or more intermediary values, our function calls will get more and more tangled up.

The Pattern in Elixir

Instead of writing each function to take in exactly the arguments it needs, and returning a single value, let’s broaden our scope.

Let’s create a larger, all-encompassing state object that will contain all inputs, intermediary values, and outputs of our function chain.

In our case, we’ll need the sms input, the user object, and our system’s response:

%{sms: sms, user: nil, response: nil}

We can then rewrite our get_user, get_response, and send_response methods to take our state object as an argument, and return a (potentially modified) state object as a result:

def get_user(state = %{sms: %{from: from}}) do
  %{state | user: ...}

def get_response(state = %{sms: %{message: message}}) do
  %{state | response: ...}

def send_response(state = %{user: user, response: response}) do

Now we can cleanly chain together all of our function calls:

%{sms: sms, user: nil, response: nil}
|> get_user
|> get_response
|> send_response


What’s great is that we can easily inject new functions into our chain without worrying about juggling inputs and outputs. Let’s add a function to the end of our chain that logs the entire interaction:

%{sms: sms, user: nil, response: nil}
|> get_user
|> get_response
|> send_response
|> log_interaction

In a similar vein, we can easily add debug logging (or anything else) between each step of the chain to get an in-depth look at what’s happening between each call in the chain:

%{sms: sms, user: nil, response: nil}
|> get_user
|> IO.inspect    # debug logging
|> get_response
|> IO.inspect    # debug logging
|> send_response
|> IO.inspect    # debug logging

Now in Javascript

We can apply this same pattern in Javascript. The Lodash library gives us an excellent set of tools for chaining together function calls. Let’s put them to work.

Imagine we have a similar set of functions:

function get_user({sms: {from}}) {

function get_response({sms: {message}}) {

function send_response({user, response}) {

We can use Lodash to run through our chain, just like we did in Elixir:

_.chain({sms, user: undefined, response: undefined})

Similarly, we can tap into any point of this chain to add debug logging:

_.chain({sms, user: undefined, response: undefined})
 .tap(console.debug)    // debug logging
 .tap(console.debug)    // debug logging
 .tap(console.debug)    // debug logging

What’s in a Name

There are lots of names that we can throw at this pattern. Some of them stick better than others, but I’m not fully satisfied with any of them.

I asked in the Elixir slack channel if anyone had a name for this kind of thing:

Is there a generic name for building a large, all encompassing state object, and then passing it through a lot of different functions that might only work on a subset of that state? What Plug does, for example.

I find myself doing that kind of thing a lot, and I wonder if there’s some kind of name/pattern that describes it.

Dependency injection?

Yeah, maybe. I’d describe it as maybe DI + method chaining. DI seems like a weird thing to talk about in a purely functional setting. Of course dependencies will be injected.

I was trying to look at “popular" non-Elixir projects (like Redux or Om) which use the same concept to see if they identify the pattern by a name, but I’m not seeing anything.

Dependency injection (DI) might apply in a way, but I usually think of dependency injection in terms of passing around functionality, not data. In a pure functional context, everything could be considered dependency injection in that sense.

I mentioned “method chaining”, which seems to describe a nice side-effect of the pattern, not the pattern itself.

Maybe the best pattern name would be “Middleware”, as seen in libraries like Express, React, and Plug.

The pattern used by these libraries is exactly what I’ve been describing, but I’m not sure about the name. The term “middleware” was originally used to describe something very different than what we’ve been talking about.

On top of that, there’s some disagreement amongst software developers as to whether “middleware” is the term we should be applying to this pattern (or if this is even a pattern at all).

Either way, I’ll probably refer to this pattern as middleware when talking with other developers, and I’ll definitely continue using my favorite pattern without a name.

Upgrade Releases With Edeliver

Written by Pete Corey on Jan 23, 2017.

Last week we saw that using edeliver could drastically simplify our Elixir release process. Now that we can build and deploy our initial releases, we should investigate how edeliver can help us build, manage, and deploy upgrade releases.

To get a better idea of how upgrade releases work with edeliver, let’s make a change to our original application, build an upgrade release from that change, and then deploy that change to our production server.

Configuring edeliver

Before we start building our upgrade release, we’ll need to make a configuration change to Distillery.

Recently, Distillery changed where it stores its release artifacts. If left unchanged, this new output directory would break our edeliver release process:

==> Upgrading prod from 0.0.1 to 0.0.1+82e2ed7
==> Upgrade from 0.0.1 to 0.0.1+82e2ed7 failed:
  0.0.1 does not exist at _build/prod/rel/prod/releases/0.0.1

Thankfully, we can change where these artifacts are stored with Distillery’s output_dir configuration option.

Let’s edit rel/config.exs and set output_dir to the rel/<application name> directory:

set output_dir: "rel/hello_edeliver"

Now Distillery will store our release artifacts in rel/hello_edeliver, which is where edeliver expects to find them.

Making Our Change

Let’s make a small change to our application. We’ll update our index.html.eex and add a line indicating that we’ve upgraded the application.

<p>We've upgraded!</p>

At this point, we can either manually upgrade our application’s version in our mix.exs file, or we can let edeliver manage our versioning for us.

Let’s keep things as hands-off as possible and let edeliver manage our application’s version.

At this point, we can commit our changes and move on to building our upgrade.

git commit -am "Added upgrade message."

Building and Deploying Our Upgrade

Elixir upgrade releases are always built off on a previous release. Distillery will generate a patch that changes only what is different between the old and new version of the application.

With that in mind, we need to know what version of our application is currently running in production. We can find this out using edeliver’s version mix task:

mix edeliver version production

In our case, we can see that we’re running version 0.0.1 of our application in production.

Knowing that, we can generate our upgrade release. Upgrade releases are built with the build upgrade mix task:

mix edeliver build upgrade --with=0.0.1 --auto-version=git-revision

We’re using the --with flag to point to our previous 0.0.1 release. We’re also using the --auto-version flag to tell edeliver to automatically handle the versioning of our application.

This command will generate an upgrade release with a version similar to 0.0.1+82e2ed7. You can see that the git-revision option appended the current commit’s SHA to the end of the original release version.

For more information about upgrade flags and automatic versioning, be sure the check out the edeliver documentation and wiki.

Once our upgrade release has been built, deploying it to our production environment is a simple task:

mix edeliver deploy upgrade to production

That’s it! Our change was applied instantly to our running application with zero downtime.

If we check the version of our application running in production, we should see 0.0.1+82e2ed7:

mix edeliver version production

And lastly, when we view our application in the browser, we should see our upgrade message in the DOM.


Final Thoughts

After getting over a few configuration hurdles, using edeliver to build and deploy an upgrade release was a breeze.

Being able to seamlessly deploy an upgrade to any number of hosts with zero downtime is an incredibly powerful tool, and edeliver gives a polished interface for just this.

I’m looking forward to using edeliver more in the future.

Simplifying Elixir Releases With Edeliver

Written by Pete Corey on Jan 16, 2017.

In our previous two posts, we’ve built releases manually with Distillery, and deployed an upgrade release to an existing Elixir application. As we’ve seen, this was a very hands-on process.

Thankfully, there is another tool that we can use to simplify our release process. In this post, we’ll dive into using edeliver to build and release Elixir applications.

Our Example Application

To help walk ourselves through the process of using edeliver, let’s create a new Phoenix application that we can deploy to a “production server”.

Let’s start by creating a new, basic Phoenix project:

mix hello_edeliver --no-ecto

We’ll be deploying this application as is, so let’s move onto the process of installing and configuring our release tools.

First, we’ll add dependencies on edeliver, and distillery, and add edeliver to our projects list of applications:

def application do
   applications: [..., :edeliver]]

defp deps do
   {:edeliver, "~> 1.4.0"},
   {:distillery, ">= 0.8.0", warn_missing: false}]

Note: edeliver is a high-level tool designed to orchestrate the creation, deployment, and management of Elixir releases. Under the covers, it can use Distillery, exrm, relx, or rebar to build release bundles.

Our application won’t use any “production secrets”, so to simplify this introduction to edeliver, let’s remove our dependency on the config/prod.secrets.exs file by commenting out its import_config line in config/prod.exs:

# import_config "prod.secrets.exs"

Finally, while we’re in config/prod.exs, let’s add a few vital configuration options to our HelloEdeliver endpoint:

config :hello_edeliver, HelloEdeliver.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [host: "...", port: {:system, "PORT"}],
  server: true,
  root: ".",
  version: Mix.Project.config[:version],
  cache_static_manifest: "priv/static/manifest.json"

And with that, our example application should be ready for release.

Before we move on, let’s fire up our development server with mix phoenix.server and make sure that everything looks as we’d expect.

Configuring Distillery and edeliver

Now that our application is ready, we need to spend some time configuring our deployment tools.

First, let’s create our Distillery configuration file (rel/config.exs) with the release.init mix task:

mix release.init

The default configuration options provided by release.init should be fine for our first deployment.

Next, let’s take a look at our edeliver configuration file (.deliver/config). We’ll update the provided fields and point edeliver to a remote “build host” and “production host”:




At this point, we could add any number of production hosts, or add another environment entirely, such as a staging environment.

Because we’re building a Phoenix application, we’ll need to build and digest all of our static assets before building our release.

We’re building our release bundle on our remote build host, so we’ll need to instruct edeliver to do these things for us. Thankfully, edeliver comes with a host of pre and post hooks that we can use to accomplish this task.

Let’s add a “pre compile” hook to build (npm install, npm run deploy) and digest (mix phoenix.digest) our static assets:

pre_erlang_clean_compile() {
  status "Installing NPM dependencies"
  __sync_remote "
    [ -f ~/.profile ] && source ~/.profile
    set -e

    cd '$BUILD_AT'
    npm install $SILENCE

  status "Building static files"
  __sync_remote "
    [ -f ~/.profile ] && source ~/.profile
    set -e

    cd '$BUILD_AT'
    mkdir -p priv/static
    npm run deploy $SILENCE

  status "Running phoenix.digest"
  __sync_remote "
    [ -f ~/.profile ] && source ~/.profile
    set -e

    cd '$BUILD_AT'

By default, edeliver will store all release tarballs in the .deliver/releases folder. Let’s preemptively exclude this folder from revision control:

echo ".deliver/releases/" >> .gitignore

The last thing we need to do to prepare for our first release is to commit all of our changes!

Preparing Our Hosts

When using edeliver, we’ll always have at least two different types of remote environments.

The first is our build host. This is where edeliver actually builds our release. In our case, it’s running a variation of a mix release command. As we saw in a previous article, it’s important that the build host be nearly identical to the production host in terms or architectures, etc…

Our build host has several dependencies. We’ll need to install Git, Erlang & Elixir, and Node. Thankfully, we’ll only need to provision a single build host.

The second type of host is our deployment target. These machines will be running our application in environments such as staging or production. We can have any number of these hosts living in the wild.

Our deployment machines have no dependencies. We don’t even need to install Erlang - our release will bring it along for us.

However, we do need to set any required environment variables on these hosts. Out of the box, a Phoenix application needs a PORT value. We can export this from our ~/.profile:

export PORT=4000

If you’re using Amazon EC2 hosts, you’ll most likely authenticate with your remote hosts by passing along a *.pem file when you establish your SSH connection.

While edeliver doesn’t explicitly support this kind of authentication, adding a Host/IndentityFile entry in your ~/.ssh/config file for each of your remote hosts will authorize edeliver to communicate with these hosts:

  IdentityFile ~/my_identity_file.pem

  IdentityFile ~/my_identity_file.pem

Making Our Release

Once our application is ready, our deployment tools are configured, and our hosts are provisioned, we can build and deploy our release.

The first step is to instruct edeliver to build our release on our build host:

mix edeliver build release

Success! If everything went well, we should find our newly built release tarball in our release store (.deliver/releases).

Next, let’s push our initial release up to our production server:

mix edeliver deploy release to production

Another success! We’ve deployed our initial release to our production environment.

Now let’s fire up the Phoenix application in production:

mix edeliver start production

We can check that everything went well by using edeliver to ping our application:

mix edeliver ping production

If our application is up and running, we should receive a pong reply to our ping.

At this point, we should be able to navigate to our production host and find our application running at the port we’ve specified.

Final Thoughts

From my limited experience, edeliver is a fantastic tool.

While it does require up-front work (more work than using Distillery on its own), that work is purely up-front. Once you’ve provisioned your build host and set up your edeliver configuration file, building and deploying releases to any number of hosts is smooth sailing.

I’m excited to work more with edeliver. Expect an upcoming post on deploying hot upgrade releases to see how the process compares with just using Distillery.