Processes In Elixir (part 1)

Owais Qayum
5 min readOct 26, 2020

--

The fundamental units of concurrency in the elixir are processes. Don't confuse them with operating system processes. Elixir processes are much smaller in size and only take few microseconds to create¹.

Actor Concurrency Model²

Erlang uses the actor concurrency model and that's why the elixir uses it too. Some key features are included in the actor concurrency model. Actors are like humans. Let's discuss them one by one.

  1. Every actor is a process.
  2. Each process is having its own specific task.
  3. A process is usually in an idle state. It gets initiated when a message is sent to it. When a message gets pattern matched with a process then it receives that message in its mailbox and replies back with a message.
  4. The process never shares its information with any other process. Hence, it's always independent in nature.

Let's understand the processes and actors in another way. For example, my friend tells me to bring a book from the market (message sent by a process). Now, its pattern matched with me and I will respond by bringing the book. Now, if my friend asks me to take a lion home, then I will simply ignore that message (not pattern matched with me). Also, I don't know what's going on in my friend's head and he doesn't know anything about my head as well (processes never share information).

Creating Weather Application²

So, here we will be creating a weather application and will look at how processes can have an impact on the overall application. The working of the application is simple and can be finished in three steps.

  1. Accepting a single argument containing the location.
  2. Requesting information from a weather API.
  3. Weather API either replies with {:ok, temperature} or {:error, reason}.
  4. The temperature is displayed alongside the location is the response is :ok.
Weather Actor Handling a single request (source)

Let's say it takes the application to respond one second for every location, then how much time will it take to process the 1000th location. This application will be useless if someone has to wait for 1000 seconds to get his/her result. So, here comes the processes in action. All the responses and requests will be concurrent and hence will take much lesser time to execute all 1000 queries. One important property of concurrency is that

You never know the final responses. Some might respond quicker than others.

For example, we input the list of 1000 cities in alphabetical orders then in processes, it's not necessary that we will get the output in alphabetical order as well.

Reason?

Because each process is independent in nature and we don't know how much time does each process takes in order to give some results.

The basic version of the Weather application²

In the basic version, we will simply create the app in 4 steps

  1. We will add HTTPoison and JSON dependencies to the project.
  2. Then we will make an HTTP request to Weather API³ and will get a response in the form of ok or an error message.
  3. As a result of step two, we will get a JSON response and then we will take our desired temperature data using pattern matching.
  4. Then we will simply print the data(temperature) with the location.

Creating the Project in Elixir

creating a new project

Here you will create a new mix project with the name weather.

contents of weather app

Getting the API key for Weather Data

First of all, go to the Open Weather Data website and create your account. Then you will be granted an API key that you will simply paste into the code you will see in the coming up section.

Do not give this API to anyone.

Installing the Dependencies

in order to install the dependencies, we will simply go to mix.exs file and under deps we will add the following dependencies. Kindly update the version number according to the latest one.

HTTPoison library can be found here and JSON can be found here.

adding dependencies

Then simply when you are in mix directory in terminal run mix get.deps. Now you are ready to go. Create a file under lib directory worker.ex. Here is the code that will go in worker.ex.

Now let's explain this code. You all can see the line numbers so I will be referring to code lines.

code line 1: we created a module named Weather.Worker as Weather is our main module and the worker is a submodule of Weather.

code line 3: we created a function named “temperature_of” that will take the name of any city in the world, let's say “Islamabad”.

code line 4 (url_for(location)): here the city name will be passed as an argument to url_for and the function url_for will be called on line 16. Here the URL will be encoded and the city name will be given to line 18 and that will be returned by this url_for function.

ouput: “url_for: “http://api.openweathermap.org/data/2.5/weather?q=Islamabad&appid=your_api_code"”

code line 5 (HTTPoison.get): HTTP.poison will get the above link as an input and will grab all the data from the API as shown below

The result from HTTP.poison is very jumbled and not that much understandable. So, we will use the parse_response function on line 6 to clean the data.

code line 6 (parse_response): So the above data will be given to function parse_response which will give the result only if it has a body, and status code of 200 as shown in line 24 else it will generate an error as shown on line 30.

Then that data will get cleaned if the pattern matches using the JSON.decode command on line 23. So, if the result was ok then we will get the temperature in as shown on line 10 else we will get the error message as shown on line 12.

In the next section, we will see how we can implement the app using processes.

  1. Joe Armstrong, “Concurrency Oriented Programming in Erlang,” Feb. 17, 2003, http://mng.bz/uT4q.
  2. Hao, B. (2017). The little Elixir & OTP guidebook. Shelter Island, NY: Manning Publications Co.

--

--

No responses yet