Before you read this Article, I highly recommend you read the article about GenServer:
https://dev.to/postelxpro/read-this-article-if-you-want-to-learn-genserver-1l24
Do you want to learn Elixir in three months? https://elxpro.com/sell
Greeting
Hello #devElixir!!! Welcome to #FullStackElxpro
Here, we discuss strategies and tips for your Elixir learning journey from zero to an expert in 3 months.
I am Gustavo, and today's theme is **Setup your local machine to use Elixir**.
ps: You can follow the Article with a VIDEO
Want to learn more about Elixir on a Telegram channel?
https://elxpro.com/subscribe-elxcrew
What is the difference between Supervisor and DynamicSupervisor?
Before understanding the difference between Supervisor and DynamicSupervisor. Let`s read and understand both.
Supervisor
https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html
https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html
A supervisor is a process that supervises other processes, which we refer to as child processes. Supervisors are used to building a hierarchical process structure called a supervision tree. Supervision trees provide fault tolerance and encapsulate how our applications start and shut down.
In my experience as a Developer in general, Supervisor is a way to keep the lifecycle of my Elixir Web Applications and a way to start and manage the essential dependencies you will have in your App. E.g., Ecto, Phoenix, Oban, Broadway.
Suppose you understand how Supervisor Works. It will be much easier to create dependencies of processes and how to start them quickly. Building Elixir applications and understanding core frameworks will be more straightforward in that case.
DynamicSupervisor
A DynamicSupervisor starts with no children. Instead, children are started on demand via start_child/2. When a dynamic supervisor terminates, all children are shut down at the same time, with no guarantee of ordering.
https://hexdocs.pm/elixir/1.13/DynamicSupervisor.html
https://elixir-lang.org/getting-started/mix-otp/dynamic-supervisor.html
DynamicSupervisor starts the process when is necessary, and you can see it easily when you have a Browser opened or a query execution using Ecto. I like creating associations during our typical day as an Elixir Developer because most of the time you will not use DynamycSupervisor/Supervisor. But they are there, you are using them, and you probably will need to debug or understand a piece of code in our core frameworks like ECTO/Phoenix or others. That is why understanding the difference between them and maybe in a day use them.
What's worth more? Use Supervisor or DynamicSupervisor
I think you will use both but in a different context
Do you remember any stories where this was important to you?
Yes, I do. I remember when I knew only to use Phoenix and Ecto barely, and I had some problems with those frameworks and lifecycles. And also, I was encouraging myself to learn deeply about how Phoenix, Ecto, and Elixir work.
I had no idea why the application.ex was in my phoenix applications, no idea how the process and supervisors tree works, no idea how a phoenix app works. And I lost a lot of productivity in my day as an Elixir developer because I did not know why/how they worked and why they were there. When I decided to study how they worked and research both, my life as an Elixir developer changed. Elixir's level of skill and productivity was raised 10x more because I only understood how they work.
Where do you see people get it wrong the most?
The main problem is you feel comfortable using only libs like Phoenix and Ecto for more than 10 months. Because if you don`t understand how your elixir application works, you will face problems scaling apps using dependencies like Oban, Broadway, or frameworks to use Cache, MongoDb, and even simple GenServer.
The best way in my experience is:
- Am I okay to create standard Phoenix Apps?
- Now I am going to study how Process works.
- Do I know how to make a GenServer/Agents and Tasks? I am going to look at it.
- Do I understand how Supervisor and DynamicSupervisor work? I am good at learning it.
Where to start?
Level 1
Start a standard Elixir app
❯ mix new practice
and create a GenServer
defmodule StocksV1 do
use GenServer
def start_link(name: name, valuation: valuation) do
GenServer.start_link(__MODULE__, valuation, name: name)
end
def init(state) do
{:ok, state}
end
def handle_cast({:add, value}, state) do
state = state + value
{:noreply, state}
end
def add(stock, value) do
GenServer.cast(stock, {:add, value})
end
end
Lets Play around with our Genserver.
iex(4)> StocksV1.start_link name: :etsy, valuation: 10
iex(5)> :sys.get_state :etsy
iex(6)> GenServer.cast :etsy, {:add, 30}
iex(7)> :sys.get_state :etsy
How about we want to start our stock within our App?
In this case, we can use Supervisor but how to start it?
It is simple, but we need to use the application because we are learning the whole process we need to use the application. And Application is essential for our Libs and Elixir application.
Read more: https://hexdocs.pm/elixir/1.13/Application.html
Applications are the idiomatic way to package software in Erlang/OTP. To get the idea, they are similar to the "library" concept common in other programming languages, but with some additional characteristics.
straightforward to use it, you only need to add in your mix.exs
def application do
[
extra_applications: [:logger],
mod: {Practice.Application, []}
]
end
create application.ex
defmodule Practice.Application do
use Application
def start(_, _) do
children = []
Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
end
end
Every time that you create an Application you must create an :erlang.link and in this case our link is our Supervisor. After starting the Supervisor you can only add your process to run:
defmodule Practice.Application do
use Application
def start(_, _) do
children = [
{StocksV1, name: :etsy, valuation: 10},
# {StocksV1, name: :appl, valuation: 10}
]
Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
end
end
But you will notice that one of them is commented because you need IDS, and we can`t start it when we want but when we start the application, which makes us move to the next step. Start using DynamicSupervisors.
`
defmodule Practice.Application do
use Application
def start(_, _) do
children = [
{Registry, keys: :unique, name: Stocks},
{DynamicSupervisor, strategy: :one_for_one, name: Stocks.DynamicSupervisor}
]
Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
end
end
`
`
defmodule Stocks do
use GenServer
def start_link(name: name, valuation: valuation) do
name = stock_name(name)
GenServer.start_link(MODULE, valuation, name: name)
end
def stock_name(name) do
{:via, Registry, {MODULE, name}}
end
def init(state) do
{:ok, state}
end
def handle_cast({:add, value}, state) do
state = state + value
{:noreply, state}
end
def create_stock(name, valuation \ 20) do
DynamicSupervisor.start_child(
Stocks.DynamicSupervisor,
{Stocks, [name: name, valuation: valuation]}
)
end
def add(stock, value) do
stock = stock_name(stock)
GenServer.cast(stock, {:add, value})
end
end
`
When you call create_stock, different of a GenServer, you will create a child for your DynamicSupervisor and then. Create a process_id linking to your Parent's process.
`
iex(1)> Stocks.create_stock "apple", 100
{:ok, #PID<0.175.0>}
iex(2)> Stocks.create_stock "alphabet", 300
{:ok, #PID<0.177.0>}
iex(3)> :sys.get_state pid("0.175.0")
100
`
Because we are using Registry, the way that we are creating processes is different. that is why we have the function stock_name, creating the unique ID to our process and then change the state.
iex(4)> Stocks.add "apple", 300
:ok
iex(5)> :sys.get_state pid("0.175.0")
Wrap up
If you followed this article, you will notice how simple is to use both of the services when you understand how the process works.
Social networks:
- Gustavo Oliveira - https://www.linkedin.com/in/gustavo-oliveira-642b23aa/
- Elxpro Linkedin - https://www.linkedin.com/company/36977430
- Twitter - https://twitter.com/elx_pro
- Elxpro - https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ
Top comments (0)