foggy

foggy

Help understand concurrency and concurrency issues

I personally picked up Elixir by converting a high-throughput Rails API (that was having scaling issues) to a Phoenix API. I had previous experience scaling the Puma webserver on Rails for an API that backed a mobile application, and while the right settings led to success in that instance, this particularly API was just high-burst throughput at set intervals and I had no idea how to get the right configuration w/ Puma without resource-scaling through the nose.

A new webserver for Ruby got announced recently called Falcon, which is built on a more asynchronous model and can scale how it handles requests more gracefully.

How?

When I first started making web apps, everybody told me not to worry about scaling. I think it’s good advice for diving in and building something that works. But at the core of every real-world project I’ve done has been a scaling issue, and most of them have been related to dealing with throughput. I would love to better understand why running on Erlang automatically means concurrency is handled better, and why this new Ruby webserver handles these things better in spite of the fact that Ruby is weak in this area.

What are some good resources for better understanding the practical science behind this stuff?

Most Liked

easco

easco

Let’s turn to the description of Falcon from their web page:

Falcon is a multi-process, multi-fiber rack-compatible HTTP server built on top of async, async-io, async-container and async-http. Each request is run within a lightweight fiber and can block on up-stream requests without stalling the entire server process.

In particular this last sentence states that each request that comes into the server gets a dedicated “computing unit” (in this case a “lightweight fiber”) to handle that one request. This means that one request that is stalled out while communicating to a back-end system will not prevent the other requests from running.

Cowboy (a popular HTTP server for Erlang/Elixir) does something similar. Each incoming request is handed off to an Erlang Process (the “computing unit” of the system). Each of the processes runs independently so one of them stalling on an I/O operation - like the back-end system request, will not prevent the others from running.

The same idea - take a single UNIX process and handle multiple, concurrent requests, in separate “computing units” where a blocking operation in one cannot prevent the others from running.

Where Erlang “means concurrency is handled better” is in the set of tools that are built into Erlang that Ruby does not provide. The first thing that comes to mind is that Erlang Processes have isolated memory spaces. In Ruby more than one “lightweight fibers” might share the same object. A bug in one fiber could put that object into an inconsistent state leading to corruption in all the fibers.

This kind of viral corruption can happen in Erlang/Elixir as well, but only if one process sends a message to another and the receiving process doesn’t validate the incoming message before accepting it.

Another set of tools that Erlang provides is monitoring and linking between “computing units” (allowing for the OTP abstraction, Supervisors). In Ruby, if one of your “lightweight fibers” goes away, it’s just gone. The system doesn’t provide any built-in way for another fiber to know that the failing one has gone away and do something about it. So long as the developer of Falcon have done their work properly, a failure - say an unhandled exception - in one fiber shouldn’t take down other fibers or the whole system. But that has to be handled at the framework level. In Erlang, that kind of isolation is built into the base system.

OvermindDL1

OvermindDL1

Because every actor/process on the BEAM is a shared-nothing message-passing system, thus no locks, they can be run transparently on any number of cores or even across multiple distinct systems and hardware, easy to reason about as inside each process is fully immutable with only needing to reason about messages, each actor can run concurrently and in parallel, etc… I.E. things on the BEAM scale ‘almost’ for free (as long as they are not waiting on messages, which is not an issue with web based systems as distinct sockets have a tendency not to talk to each other :wink: ).

No clue about the ruby bit, I don’t use it.

Where Next?

Popular in Chat/Questions Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
332 31312 154
New
zervis
Hello, I’m about to dive into web development. I was thinking about Laravel or Ruby on Rails, but then I found Phoenix. Do you recommen...
New
wolfiton
Question: Can someone recommend me some good resources on learning performance for phoenix elixir applications and a design pattern I sh...
New
InkFlo
Hi everyone, This year I’m graduated from Bachelor Degree (in computer science) from France (not really a bachelor, the exact term is “L...
New
satoru
I’m working on the “Bob” exercise on the Elixir Track in Exercism. I am testing for uppercase letter with this simple check: c in ?A..?Z...
New
lc0815
hello from a real frustrated newbe… I’m reading this article Full-Stack React With Phoenix (Chapter 3 | Introduction to Phoenix) by mich...
New
Twfo326
As a novice dev I’m trying to keep the curriculum as lean as possible. My requirements are modest: build simple CRUD apps with Phoenix...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36820 110
New
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement