fireproofsocks

fireproofsocks

Best examples of concurrency?

Forgive an open-ended question, but I’m curious as to what the community thinks are some of the best examples of how concurrency can be helpful? Like – what are the best “recipes” you have come across?

What I’m trying to get at is what about concurrency specifically makes Elixir such a good choice. Are there specific functions (e.g. from the Task module) that you reach to regularly to handle certain problems?

Thanks for any thoughts!

Most Liked

LostKobrakai

LostKobrakai

Concurrency makes sure a large workload cannot block other concurrent workloads from making progress towards succeeding. This is needed everywhere in multi user systems – where there’s not just a single user (or you can live with the uncapped latency of sequential processing of input).

A classic example is a website where one user triggers a heavy report generation, where you don’t want other users to wait for the report to have finished before handling their requests.

Though again this comes up everywhere where you need to make progress on multiple tasks without doing it sequentially. Webservers, DB connection pools, processing pipelines and many more. Even if a specific task at hand (like processing events) might work fine being done sequentially it might still require running concurrently to different tasks of the system like sending logs off to somewhere, error reporting, some management dashboard, debugging tools and again many more.

Implementing something like this is not impossible in other ecosystems, but requires (sometimes a lot) more work to be implemented and especially to get correct. Also see virdings first law of programming.

That’s where processes, the share nothing/no global state approach and message passing of the beam round out the picture. They’re a great abstraction to be used for dividing up work between “this code meant to run sequentially as programmed, though concurrently with other processes” from “this is now a separate process, which can run concurrently to what spawned it”. This abstraction and how it can be used to model/build up larger things to do the pervious mentioned more concrete things is to me the core distinction to other languages.

And then the ability to parallelize with multiple cpu cores and move work across a cluster of nodes almost falls out for free from the pritimives.

So if you want to look at actual elixir examples:

  • Look at bandit and how it models http handling with processes. There’s a pool of acceptors (responding to the initial tcp connection coming in) and then later a process per connection and/or request (different between http versions) to handle the actual http request
  • Look at DBConnection for how ecto db connections are pooled
  • Look at Task.async_streamGenStageFlow to see how you can climb the ladder of abstraction on process pipelines, even though underneight it’s still mostly a bunch of processes arranged in a useful manner.
  • Look at Finch for pooling outgoing http request

Often you’ll not interact directly with many of these because they’re part of some library and the users of such don’t need to care, but sometimes it’s not worth pulling in a library when e.g. Task.async_stream does well enough.

dimitarvp

dimitarvp

I can give you more examples Later™ but to me Task.async_stream has been a game changer ever since I learned Elixir for the first time (almost exactly 8 years ago). It’s a beautiful way to do scatter-gather computing.

There are many embarrassingly parallel computing problems and Elixir enables you to tackle them almost transparently.

In my case I was rewriting a Ruby reporting system and there you have to process millions of separate records. Elixir lent itself absolutely perfectly to splitting these records into buckets of 1000-2000 records each chunk and process each of them in parallel. I also used ETS to aggregate some of the results and it proved itself extremely capable and was not a bottleneck even though my production code was having something like 500 separate processes update various records in an ETS table at the same time (+ counters).

Another very common pattern is task pools, of which Oban is the logical conclusion, though there is space for many more solutions on a smaller scale that don’t require DB persistence. I’d even venture to say that you haven’t properly practiced Elixir until you have written a small task pooling library for yourself.

Oh, and also DynamicSupervisor.start_child + Registry. A match made in heaven. It helps you monitor 3rd party “live” entities, like connections to user’s devices for example (something LiveView makes use of as well, though not specifically with those modules).

Where Next?

Popular in Discussions Top

AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31695 143
New
ben-pr-p
In general I’ve been sticking to this community style guide GitHub - christopheradams/elixir_style_guide: A community driven style guide ...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19740 150
New
pillaiindu
In django there is a cache framework backed by memcached. Rails also puts a lot of emphasis on caching, and even the idea of russian-doll...
New
lorenzo
Hey everone! I created a prototype for my app using Nodejs for the api. But the framework I chose wasnt great (in general theresnt any g...
New
PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
slashdotdash
Phoenix Live View is now publicly available on GitHub. Here’s Chris McCord’s tweet announcing making it public.
New

Other popular topics Top

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
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement