How requirements shaped my code, AKA Rails 5 and ActiveRecord before_destroy callbacks

I recently started a new project with Rails 5, and at some point I found out the code was not behaving as expected.
The initial scenario was quite simple, Admins can have many Phones, as this code suggests:

Continue reading “How requirements shaped my code, AKA Rails 5 and ActiveRecord before_destroy callbacks”

Test RDBMS should == production RDBMS

In Mikamai we developed svelto, our own url shortener application in 2008, but at that time the web was still on IPv4 (and it mostly is today, for what it matters). When registering visits we store also the visitor’s remote ip, and a few days ago we received a visit from an IPv6 number which ended up in an application error:

Continue reading “Test RDBMS should == production RDBMS”

Elixir: an introduction to server architecture and GenServer behaviour

Erlang (and Elixir) strongly advocates concurrency, scalability, and fault tolerance via multiprocessing and the use of specific design patterns based on it.
An Erlang process is not an operative system process: it is faster, lighter, with much smaller memory footprint.
By spawning hundreds, thousands or even millions of these processes you can achieve great scalability, as
this recent post
explains.

The server/client architecture builds on such lightweight processes, can handle state, and is one of the keys to the
great results that can be achieved using Elixir.

Let’s build a server starting from this simple calculator module code:


defmodule Calculator do
  def calc(value, operator, n) do
    case operator do
      :+ -> value + n
      :- -> value - n
      :* -> value * n
      :/ -> value / n
    end
  end  
end

Calculator.calc 50, :-, 8
# 42

This code doesn’t handle state, just as you would expect when using a functional language: for multiple operations you
need to pipe the functions:

Calculator.calc(50, :-, 8) 
|> Calculator.calc(:-, 21) 
|> Calculator.calc(:*,2)

Spawning an Erlang process is very easy, fast and cheap:
pid = spawn fn -> end
The variable pid is a reference to the process and can be used to communicate with it.
A server is basically a never-ending process
that recursively handles some kind of requests. Let’s build some looping process first, with the ability to
handle state as well. Copy and paste this code in your iex shell:


defmodule Server do
  def start do
    spawn fn -> loop(1) end
  end

  defp loop(n) do
    IO.puts "looping #{n} times"
    :timer.sleep 1000
    loop n+1
  end
end

Server.start
# looping 1 times
# looping 2 times
# ...

Every second a new message is printed on the screen: these letters come from the spawned server process,
which is non blocking (you can still use the repl) and kind of stateful
(the number is incremented after each iteration).

Let’s go back to our calculator example. Let’s write the CalcServer module that complements the
Calculator core module. Here the loop function will at first handle the incoming
messages, then recursively call itself with the new updated state:


defmodule CalcServer do
  import Calculator

  def start do
    spawn fn -> loop(0) end
  end

  def loop value do
    new_value = receive do
      {:value, caller} -> 
        send caller, value
        value
      {operator, n} -> calc(value, operator, n)
    end
    loop new_value
  end
end

Let’s play a little with it:


calc = CalcServer.start
send  calc, {:+, 23}
send  calc, {:-, 2}
send  calc, {:*, 2}

The variable calc references the calculator server process (returned by spawn),
so we can send messages to it. These messages then get pattern-matched in the loop
receive block, precisely here:
{operator, n} -> calc(value, operator, n)
The subsequent loop function will be called with the calculation result,
courtesy of the Calculator module and its function calc that has
been imported using the import Calculator directive.
The messages we sent up until this point were fire-and-forget, meaning we didn’t receive any response from the server.

But now we need to read the total, so we can resort to bidirectional communication. First we need to send
the appropriate message to the server, which replies to our process with another message that we can read in our
main process:


send calc, {:value, self}
receive do
  total -> IO.puts "Current total is #{total}"
end
# Current total is 42

We have successfully built from scratch a simple server that relies on processes and asyncronous communication.
Of course this is buggy and trivial code, but it was useful to analyze some details behind the GenServer architecture.

Now that we have a grasp of how things works, we can convert the existing code to use the GenServer behaviour. GenServer stands for “generic server”,
an abstraction/design-pattern that helps build servers with consistent and predictable interface. Here is the new server code:


defmodule CalcGenServer do
  use GenServer

  import Calculator

  def start do
    GenServer.start __MODULE__, 0
  end

  def handle_call :value, _, value do
    {:reply, value, value}
  end
 
  def handle_cast {operator, n}, value do
    {:noreply, calc(value, operator, n)}
  end
end

In order to use the GenServer behaviour we only need to define a few functions: start, with the
module name to delegate calls and casts (here the current module with __MODULE__), and the start value 0.

Casts are requests that don’t need an answer, fire-and-forget. Calls are requests that require an answer, and here we have
one example of each: reading the total value is a call, while operations with the calculator are handled with a cast.

Now, here is how we can use the new server:


{:ok, calc} = CalcGenServer.start
GenServer.cast calc, {:+, 84}
GenServer.cast calc, {:/, 2}
GenServer.call calc, :value 
# 42.0

This is fairly straightforward, and we don’t need to listen explicitly for responses anymore, as we did with the
previous example.

In this post we just scratched the surface of GenServer, for a detailed introduction and explanation I strongly recommend reading the official Elixir
documentation.
Happy coding!

Testing with Espec and Elixir

Every (new) language comes with a test library, and Elixir is no exception: the name of the built-in one is ExUnit and
you can find the documentation here.

ExUnit is a good start: it is natively integrated in mix and has a few options to customize its output,
still when I use it I feel its assertion syntax is a bit harsh. So I’ve recently started using Espec,
a different testing library ispired by the awesome ruby Rspec testing framework.

Unlike other alternatives this library is not built on ExUnit, so you can’t mix the two assertion syntaxes for example,
but on the other hand you get a more polished finish.

How it works

It’s very easy to add Espec to your project; first create the project:

mix new espec_demo --module EspecDemo

then edit the mix.exs file as follows:


 def deps do
  [
    ...
    {:espec, "~> 0.8.11", only: :test}
  ]
end

def project do
  [
    ...
    preferred_cli_env: [espec: :test]
  ]
end

The shell command to run the specs is MIX_ENV=test mix espec, but thanks to the preferred_cli_env: [espec: :test] directive
you can avoid prepending MIX_ENV=test everytime you run them.

Run mix deps.get in order to download the dependecies code then run mix espec.init in order to bootstrap Espec.
This will generate a few files under the spec folder: spec_helper.exs which contains some configuration and
example_spec.exs, which includes a brief example of what can be done with Espec:


defmodule ExampleSpec do
  use ESpec

  before do
    answer = Enum.reduce((1..9), &(&2 + &1)) - 3
    {:shared, answer: answer} #saves {:key, :value} to `shared`
  end

  example "test" do
    expect shared.answer |> to(eq 42)
  end

  context "Defines context" do
    subject(shared.answer)

    it do: is_expected.to be_between(41, 43)

    describe "is an alias for context" do
      before do
        value = shared.answer * 2
        {:shared, new_answer: value}
      end

      let :val, do: shared.new_answer

      it "checks val" do
        expect val |> to(eq 84)
      end
    end
  end

  xcontext "xcontext skips examples." do
    xit "And xit also skips" do
      "skipped"
    end
  end

  pending "There are so many features to test!"
end

If you used Rspec with ruby you should feel at home with Espec: before, subject, context, describe, let, pending, expect are all there
to make you feel comfortable, and if it wasn’t for a few details you could think this was actually ruby code 😉

How to rotate Rails logs

How to rotate Rails logs