54
loading...
This website collects cookies to deliver better user experience
iex(1)> process = spawn(fn -> IO.puts("hey there!") end)
Hey there!
#PID<0.108.0>
mix new otp_test --sup
cd otp_test
defmodule Store.Struct do
@enforce_keys [:name, :employees]
defstruct [:name, :employees]
end
defmodule Core.Store do
use GenServer
alias Store.Struct, as: Store
def start_link(%Store{} = store) do
GenServer.start_link(__MODULE__, store, name: String.to_atom(store.name))
end
@impl true
def init(%Store{} = store) do
{:ok, store}
end
@impl true
def handle_call(:store, _from, %Store{} = store) do
{:reply, store, store}
end
@impl true
def handle_cast({:add_employees, amount}, %Store{} = store) do
store =
store
|> Map.put(:employees, store.employees + amount)
{:noreply, store}
end
end
iex -S mix
iex(1)> store = %Store.Struct{name: "test1", employees: 2}
%Store.Struct{employees: 2, name: "test1"}
iex(2)> Core.Store.start_link store
{:ok, #PID<0.164.0>}
iex(3)> GenServer.cast String.to_atom(store.name), {:add_employees, 4}
:ok
iex(4)> GenServer.call String.to_atom(store.name), :store
%Store.Struct{employees: 6, name: "test1"}
defmodule Store.Management do
alias Store.Struct, as: Store
def open(%Store{} = store) do
store
|> Core.Store.start_link()
end
def get_store(%Store{} = store) do
GenServer.call(String.to_atom(store.name), :store)
end
def add_employees(%Store{} = store, amount) do
GenServer.cast(String.to_atom(store.name), {:add_employees, amount})
end
end
iex(7)> store = %Store.Struct{name: "test2", employees: 3}
%Store.Struct{employees: 3, name: "test2"}
iex(8)> Store.Management.open store
{:ok, #PID<0.179.0>}
iex(9)> Store.Management.add_employees store, 4
:ok
iex(10)> Store.Management.get_store store
%Store.Struct{employees: 7, name: "test2"}
defmodule Store.Supervisor do
use Supervisor
alias Store.Struct, as: Store
def start_link(init_arg) do
Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
def init(_init_arg) do
children = [
create_store(%Store{name: "Test1", employees: 2}),
create_store(%Store{name: "Test2", employees: 2})
]
Supervisor.init(children, strategy: :one_for_one)
end
defp create_store(%Store{} = store) do
%{
id: String.to_atom(store.name),
start: {Core.Store, :start_link, [store]}
}
end
end
:one_for_one
, which restarts each time one of them dies.defmodule OtpTest.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: OtpTest.Worker.start_link(arg)
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: OtpTest.Supervisor]
Supervisor.start_link(children, opts)
Store.Supervisor.start_link([])
end
end
iex(1)> Supervisor.which_children Store.Supervisor
[
{:Test2, #PID<0.143.0>, :worker, [Core.Store]},
{:Test1, #PID<0.142.0>, :worker, [Core.Store]}
]
iex(2)> Supervisor.which_children OtpTest.Supervisor
[]
iex(3)> :sys.terminate :Test1, :kill
:ok
iex(4)>
18:56:44.901 [error] GenServer :Test1 terminating
** (stop) :kill
Last message: []
State: %Store.Struct{employees: 2, name: "Test1"}
nil
iex(5)> Process.whereis :Test1
#PID<0.149.0>
iex(6)>