Almost all of the today's software development is going toward microservices. It is ultimate goal or at least distant desirable destination to be reached once in the future for many software solutions. Why is that and what options do we have?
It is not a surprise. Having a solution developed this way, it’s maintainability becomes significantly improved, a solution is scalable and fault-tolerant. It is like comparing a classic toy with a toy made from Lego bricks. A classic toy is what it is; its build is monolithic. It’s hard to add anything, to change the shape of it and if some part breaks it is hard to fix it. On the contrary, a toy made from Lego bricks is flexible in every possible way. You can change it, reshape and if one brick breaks it is no problem to replace it. It is kind of the same with microservices.
How to build such application?
There is an endless stream of technologies on the market providing various aspects on how to solve this mystery. Every one of them is solving one piece of the puzzle. We might generate pretty good results by choosing them wisely. If there is no available technology for our particular problem, we can produce own piece of software, which is of course costly. Going to the land of microservices isn’t an easy task. Having all in one place would help.
Let me describe my dream technology for such task. It is a programming language. I don’t want any side technology other than a programming language. It is modern and makes a developer happy when they work with it, as Ruby does. It must be mature and battle proven, even it is modern. It must be possible to be used to write a distributed application. It must be scalable and fault-tolerant. Is it too much to ask? Not for Elixir.
Let me shortly explain this claims about Elixir programming language.
Elixir was developed by José Valim in 2011. He was exploring ways to improve the performance of multithreading in Ruby programming language. He studied how it is solved in Erlang VM and fell in love. The only things he didn’t like is what was not there, macro system and polymorphism via protocols. He added the parts he considered missing to make the language more extendable. The new language was forged.
It is a functional programming language so there are no loops. In the code example above we use recursion to solve the problem. Notice how there are no semicolons and parentheses.
It is a new programming language but yet mature. How is it possible?
Elixir compiles into same binary code as would Erlang and runs inside Erlang VM (BEAM). Similar goes for Scala and Clojure that run in JVM. Both Scala and Clojure are functional programming languages while Java is not. Both Erlang and Elixir are functional programming languages. What we say about Erlang, the same goes for Elixir.
So, basically Erlang and Elixir have different syntax but compile into the same binary code and run on the same Virtual Machine.
Erlang has been around for a very long time. It was developed in 1986 by Ericsson. They were solving the problem of telecom switches which had to handle a lot of connections. Each connection is two or more users having a telephone call. Each user is connected to a node. There could be multiple nodes which talk to each other. So any user can talk to any other user, it doesn’t matter if they're on the same node or not. See Figure 1.
More than 40% of today's 3G telecommunication traffic goes through Erlang. If you are using a phone, mobile phone or SMS there is a good chance that you are using Erlang. If you are using Whatsapp application, there is a 100% chance you are using Erlang. Whatsapp runs entirely on Erlang. They have 2 million connections per server and servers are connected into a cluster.
As we can see from live production examples, Erlang is a mature technology that runs mission critical applications for decades.
Scalable and Distributed
The whole concept is based concurrency. This is achieved by running tiny processes. A lot of them, like hundred thousand. Do not be confused with the process we have in OS. These processes are in Erlang and they are lightway. It is cheap to spawn them. To communicate with them, we use built in messaging system. This way each process can send a message to any other process and receive a response if needed. To achieve this, Erlang process has built in a mailbox. Once a message arrives, it waits to be read. Based on the message content a process can decide if it wants to do something like computation, to change state or to send a message back or to some other process. Each process has a mailbox, and arbitrary it can have a state and computation. See Figure 2.
The processes are independent and do not share any value or memory. If we want to exchange data between them, we have to send messages.
Each module can be run in a separate process or we can have multiple instances of the same process to do the same job in parallel. This way workload distributed among CPU cores is very efficient since the whole application is distributed.
Today everything runs on multicore CPUs; even smart watches have two CPU cores. Modern CPU design is going toward power efficient CPU with a lot of cores, especially on small devices. We are entering Internet of things era and Elixir fit perfectly. That's useful for embedded devices but what about big servers? Elixir on Erlang VM has a cluster out of the box using OTP. Officially Erlang is called Erlang/OTP where OTP stands for Open Telecom Platform. It has a bit unfortunate name. The platform was not made only to solve telecommunication problems. It is a generic framework that helps implement Erlang application.
One component of OTP is library named gen server. It implements easier communication between processes. As processes can leave on a different physical server, it makes applications developed in Erlang distributed. We can easily add more servers to a cluster or remove servers from a cluster; an application will not crash.
Everything today goes toward microservices to build a scalable and distributed application. A lot of technologies combine to create such application. It complicates development. On the other side, Erlang/OTP has it all built in, no need to for other technologies. Erlang/OTP is made for microservices.
There are two types of bugs. Those you can reproduce and those you cannot. Those you can reproduce will be discovered and fixed. Those you cannot reproduce will crash your application time to time. Let’s say you are decoding wrongly formatted JSON file. It will crash an application even if it does not have anything to do with the main flow of an application. If you want to prevent that, you will put a related code into try catch block. It is a bit awkward way to solve a problem. Your application is crashing, and you are isolating the part of it to prevent the whole application from crashing. You have to address all such parts of an application. If you miss some, your application will ultimately crash.
How does Elixir cope with this? In Erlang world there is paradigm “let it crash”. If you cannot fix the bug you let the process crash. Remember, processes are isolated and crashing one of them does not affect others. In OTP there is Supervisor library which monitors processes and other supervisors. When a process crashes, you can easily restart it. It is possible to organise supervision into a supervision tree.
See figure 3.
This way, if the process keeps crashing, we can restart supervisor which supervise the process. If it still keeps crashing we can restart supervisor which supervise the supervise and so on. In the end you might restart the whole application if needed. That means something went wrong.
Keep in mind, there is no need to crash parts of the application which are not causing the problem. Applications written in Erlang can run for years and achieve 99.9999999% uptime. It is even possible to upgrade an application without the need to restart it. It is supported in the OTP.
All of this makes Elixir a perfect candidate to develop scalable, distributed and fault-tolerant applications. In my opinion, it is a really hot technology on the market, and a lot of other people see Elixir also as the best programming language to learn next. I’m learning it at the moment and I’m really excited to develop a truly distributed application using Elixir.