Elixir Supervisor Introduction

This is a simple introduction to OTP in Elixir.

The sample is based heavily upon Introducing Elixir.

This will demonstrate how Elixir keeps a server alive across code recompilation, and restores a server after it has crashed.

This assumes that you have installed Elixir.

On a mac you can install this with (there are other solutions on other platforms):

brew install elixir

Start by cloning the repo:

git clone https://github.com/chriseyre2000/drop_server.git

Change directory into the drop_server folder.

Type

iex -S mix

This will start the application running inside the interactive Elixir REPL.

This application has a DropServer.Worker being monitored by a supervisor.

First you can calculate the velocity after falling a distance in meters:

(Type the bit after the iex> prompts):

iex(1)> DropServer.Worker.calculate_drop(40)

{“ok”, 28.0}

iex(2)> DropServer.Worker.calculate_drop(41)

{“ok”, 28.347839423843222}

iex(3)> DropServer.Worker.calculate_drop(42)

{“ok”, 28.691462144686877}

iex(4)> DropServer.Worker.how_many_calls

So far calculated 3 velocities.

:ok

You can even recompile the DropServer.Worker while it is running:

iex(5)> c(“lib/drop_server/drop_server.ex”)

warning: redefining module DropServer.Worker (current version loaded from _build/dev/lib/drop_server/ebin/Elixir.DropServer.Worker.beam)

lib/drop_server/drop_server.ex:1

warning: redefining module DropServer.Worker.State (current version loaded from _build/dev/lib/drop_server/ebin/Elixir.DropServer.Worker.State.beam)

lib/drop_server/drop_server.ex:4

[DropServer.Worker, DropServer.Worker.State]

This even maintains the state:

iex(6)> DropServer.Worker.how_many_calls

So far calculated 3 velocities.

:ok

Now if you give it some invalid data Elixir will do the classic Erlang thing and let it crash!

iex(7)> DropServer.Worker.calculate_drop(-1)

21:49:21.278 [error] GenServer DropServer.Worker terminating

** (ArithmeticError) bad argument in arithmetic expression

(stdlib) :math.sqrt(-19.6)

(drop_server) lib/drop_server/drop_server.ex:44: DropServer.Worker.fall_velocity/1

(drop_server) lib/drop_server/drop_server.ex:20: DropServer.Worker.handle_call/3

(stdlib) gen_server.erl:661: :gen_server.try_handle_call/4

(stdlib) gen_server.erl:690: :gen_server.handle_msg/6

(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Last message (from #PID<0.133.0>): -1

State: %DropServer.Worker.State{count: 3}

Client #PID<0.133.0> is alive

(stdlib) gen.erl:169: :gen.do_call/4

(elixir) lib/gen_server.ex:921: GenServer.call/3

(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

(elixir) src/elixir.erl:265: :elixir.eval_forms/4

(iex) lib/iex/evaluator.ex:249: IEx.Evaluator.handle_eval/5

(iex) lib/iex/evaluator.ex:229: IEx.Evaluator.do_eval/3

(iex) lib/iex/evaluator.ex:207: IEx.Evaluator.eval/3

(iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1

** (exit) exited in: GenServer.call(DropServer.Worker, -1, 5000)

** (EXIT) an exception was raised:

** (ArithmeticError) bad argument in arithmetic expression

(stdlib) :math.sqrt(-19.6)

(drop_server) lib/drop_server/drop_server.ex:44: DropServer.Worker.fall_velocity/1

(drop_server) lib/drop_server/drop_server.ex:20: DropServer.Worker.handle_call/3

(stdlib) gen_server.erl:661: :gen_server.try_handle_call/4

(stdlib) gen_server.erl:690: :gen_server.handle_msg/6

(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

(elixir) lib/gen_server.ex:924: GenServer.call/3

However only the state is lost:

iex(7)> DropServer.Worker.how_many_calls

So far calculated 0 velocities.

:ok

iex(8)> DropServer.Worker.calculate_drop(10)

{“ok”, 14.0}

iex(9)> DropServer.Worker.how_many_calls

So far calculated 1 velocities.

:ok

The supervisor has restarted the server.

In a real service the state would have been kept in a distinct service possibly with some form of persistence.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s