I just learnt Tasks, GenServers, Supervisors and it feels awesome. What else should I know?

As the title says, I just learnt GenServer, Tasks and Supervisors.

PragmaticStudio course on Elixir & OTP is awesome. I learnt how they can be implemented from scratch as well.

I was scared of those names, thinking they will be as complicated as some of the other languages, but damn.

I am so happy. Even wrote a rudimentary Cron job with GenServer!

So, seniors, what else should I know from OTP land?

I want to learn as much as possible before Phoenix 1.7 final release, so I have the full picture. (I purchased 4 books, but asking if I should get even more.)


P.S. LiveBook is tremendously helpful. I am spawning and killing processes left and right.

P.P.S. Is there a :hydra restart strategy, so when I kill a process, 2 take its place! :sweat_smile:

10 Likes

Learning how to handle the data structures in a more intelligent way is big:

5 Likes

DynamicSupervisors, Registry
PubSub(both Phoenix.PubSub and :pg), Presence, these two demistify a lot about phoenix channels and liveview and it still blows my mind it all works out of the box.
:gen_statem is useful from time to time though rare in most webapps I’ve seen
Composing ecto queries to dinamically generate filters
And in general something about immutable data structures and how to traverse data, which is super simple but looks complicated at first. You can write a full blown schema validation library with very little code.

These are things that I found to be super useful in an almost day to day basis or in general tools I’m glad to have in my toolbelt

8 Likes

Yesss those tools are so cool, I felt exactly the same way. Other stuff I liked learning about

  • the Erlang Observer
  • ETS tables
  • binary pattern matching

Also https://protohackers.com/ is a fun way to learn about some of these concepts (including genservers, supervisors, tasks, etc) if you like that sort of thing, there’s a forum thread on it somewhere, worth poking at it to see if you think it’s fun

9 Likes

Thanks guys,

I will keep reading and updating here about the progress I make. And will keep asking for more to learn.

Just learning the basics have cleared so much doubt in my mind and opened up so many possibilities. I can’t imagine how it will feel like, once I know everything.

1 Like

Folks here covered almost everything I was going to say. One thing though, yesterday while solving an advent of code problem I decided if I could use gen_fsm … always wanted to do that. Apparently it’s gen_statem now and really loved the way it made me think, so that could be one OTP goodness you can add? I’d also throw in a gen_event here.

2 Likes

Oh yes and to piggy back off the gen_* things… GenStage and Broadway are quite nice. Even if you don’t need them you can learn a lot reading how they are implemented.

2 Likes

Once You know Otp, the next tools are for distribution…

libcluster, horde, riak_core, syn to name a few…

Then You realize You still know nothing about Nerves or Nx :slight_smile:

It might be a small language, but the ecosystem is huge.

5 Likes

After listening to suggestions, I kind of got a hoarding problem now. :sweat_smile:


Purchased Elixir Patterns book today!


Got the following books a few days back:

  1. Programming Phoenix LiveView
  2. Real-Time Phoenix
  3. Programming Ecto
  4. Concurrent Data Processing in Elixir

Finished:
Courses on Elixir, OTP & LiveView from PragmaticStudio


P.S. Hope the Elixir Patterns book comes in a EPub format, after final release, as I want to read the book on my iPad.

1 Like

+1, In the same spirit I’d recommend to learn about IO lists / IO data as well (the secret sauce which makes Elixir/Phoenix so efficient for web stuff):

6 Likes

IO Data is so cool.

Template of doom was a great read.

1 Like

I learnt :queue.

I wish Erlang had pipe support like Elixir does.

How do you use Erlang stuff? Do you try to mould it to fit Elixir way of doing things?

q = :queue.new()
  |> (&:queue.in(1, &1)).()
  |> (&:queue.in(2, &1)).()
  |> (&:queue.in(3, &1)).()
  |> (&:queue.to_list(&1)).()

Either that or use then.

2 Likes

Oban - for tasks resilient to rolling deployments, at least others have noted that to me.

1 Like

Example please. Is there another elixir thing apart from pipes for this?

Are you talking about with?

I definitely want to use it.

Before starting with Elixir, I asked my colleague, what happens to cron jobs, while apps restarts or different kinds of deploy strategies are used, or system restarts.

I didn’t get an answer, but now I do.

def do_stuff() do
  {:ok, %{a: 1, b: 2}}
end

def pipe() do
  do_stuff()
  |> then(fn {:ok, map} ->
    # do things with `map`
  end)
end

Kernel.then/2 is mostly used as a pipe stage where you can’t just use the 1st function argument.

4 Likes

Thanks @dimitarvp,

It reduced lots of redundant brackets!

Before

q = :queue.new()
  |> (&:queue.in(1, &1)).()
  |> (&:queue.in(2, &1)).()
  |> (&:queue.in(3, &1)).()
  |> (&:queue.to_list/1).()

After:

q = :queue.new()
  |> then(&:queue.in(1, &1))
  |> then(&:queue.in(2, &1))
  |> then(&:queue.in(3, &1))
  |> then(&:queue.to_list/1)

Recursion:

defmodule Q do
  def fill(list), do: fill(list, :queue.new())
  def fill([hd | tl], q) do
    fill(tl, :queue.in(hd, q))
  end
  def fill([], q), do: q
end

Q.fill([1, 2, 3])
|> :queue.to_list

Enum.reduce:

Enum.reduce([1, 2, 3], :queue.new, &:queue.in/2)
|> :queue.to_list
2 Likes

Or

value
|> Some.function
|> then(&Uses.second_arg(:foo, &1))
|> Some.other_function
2 Likes

Exactly. It’s debatable which is better but I like the the then one better.

1 Like

My collection got bigger. Sadly my brain remains empty.

I wish there was a faster way to upload everything up. :sweat_smile: