I would like to start a serie of posts related to the OTP library. OTP stands for Open Telecom Platform. It consists of a library designed to solve highly concurrent and distributed problems.
OTP is a powerful tool but it takes some time to get used to it. Actually, it isn’t that hard to deal with it, but some previous kwnoledge is requerided in order not to get disappointed.
OTP is structured in behaviours which can be seen as interfaces in other languages. OTP comes with several ones and new others can be implemented by the user. We’ll focuse on these ones:
- Generic Server
The best way to think about an OTP application is as a tree structure where the trunk is an application behaviour, the branches are supervisor behaviours, and the leafs are generic server behaviours. As in any tree, from a branch grows another branch so we could have supervisors of supervisors of supervisors…
At each level [application, supervisor, gen_server] we find the required public interface to start or stop the behaviour (or any other operation the behaviour is able to deal with). It results in branches that are able to be stoped or started independly.
OTP behaviours always follow the same patterns. Firstly, a public interface to manage different operations: start, stop, calls, etc. Secondly, a hidden core that manage the behaviours’s commom logic and finally a set of callback functions that implement the specific aspects of the problem at hand.
Remember this logic, it’ll be repeated again and again.
Our toy app
In order to undertand what an OTP application is we’re going to develop, slowly, but firmly, a tiny feed application than we’ll use from the command line, but which could also be used from a mobile app. It’ll be a basic REST server to subscribe, unsubscribe and closely follow all or favourite feeds.
The directories structure
We need a directory structure like this:
Then meaning is obvious so I won’t describe it.
This post’s goal
In this post we don’t want to achieve a very ambitious goal so this simple structure will be fine for us.
The application behaviour
Let’s start with the application behaviour. We’ll need two files:
- feeds/src/feeds.erl The behaviour’s implementation.
- feeds/ebin/feeds.app A declarative specification of the applicaction.
The application specification file looks like this:
The implementation of the behaviour application is this:
Quite simple. Just a public interface with two functions, one to start the application another one to stop it. The start function starts the feeds_sup supervisor via its public interface (the start_link() function). We put text traces in order to follow how the process is going.
The supervisor behaviour
Supervisors are in charge of workers. They define some restart strategies like if a worker dies all of them die, or if a worker dies it’s automatically started, etc. Even it can handle how to cope with dying/starting loops. Superivors can be nested as deeply as needed, no limit exists.
Our supervisor looks like this.
Not too much work in exchange of quite a lot of power.
The generic server behaviour
We’re close to have our basic OTP application up and running. By now you problably have guessed what the next step is. Right, yet another start public interface and callback function.
Let’s compile the app.
The easiest way to compile and run your Erlang shell is via a makefile.
Be carefull, makefiles require tabs (no spaces) in the rules.
Running our app
For short the explanation will be shown as a session shell.
That’s it. We have covered the basic structure of an OTP application. It’s only necessary to remember a few things:
- A directory structure.
- The application, supervisor [[supervisor]] and worker tree.
- Each branch of the tree can be started/stoped independendly.
- Client calls public api, which calls the OTP core, which calls private behaviour’s callbacks, which in turn return values to the OTP core which send them to the client.
The last point may seem confusing but all it means is that each behaviours’s structure has some gaps you have to fill in [the public interface, callbacks functions].
We’ll build some functionallity on top of this. Clone the git repository.