Alex Rozumii
Elixir Club Kharkiv, 2017
defmodule Example do
def double(x) do
:timer.sleep(2000)
x * 2
end
end
iex> task = Task.async(Example, :double, [2000])
%Task{pid: #PID<0.111.0>, ref: #Reference<0.0.8.200>}
iex> Task.await(task)
4000
defmodule Example do
def add(a, b) do
IO.puts(a + b)
end
end
iex> spawn(Example, :add, [2, 3])
5
#PID<0.80.0>
# Start a new event manager.
{:ok, pid} = GenEvent.start_link([])
# Define an Event Handler
defmodule LoggerHandler do
use GenEvent
# Callbacks
def handle_event({:log, x}, messages) do
{:ok, [x | messages]}
end
def handle_call(:messages, messages) do
{:ok, Enum.reverse(messages), []}
end
end
# Start a new event manager.
{:ok, pid} = GenEvent.start_link([])
# Attach an event handler to the event manager.
GenEvent.add_handler(pid, LoggerHandler, [])
#=> :ok
# Attach an event handler to the event manager.
GenEvent.add_handler(pid, LoggerHandler, [])
#=> :ok
# Send some events to the event manager.
GenEvent.notify(pid, {:log, 1})
#=> :ok
GenEvent.notify(pid, {:log, 2})
#=> :ok
# Call functions on specific handlers in the manager.
GenEvent.call(pid, LoggerHandler, :messages)
#=> [1, 2]
GenEvent.call(pid, LoggerHandler, :messages)
#=> []
defmodule LoggerHandlerWatcher do
@doc """
inits the GenServer by starting a new handler
"""
def init(logger_pid) do
start_handler(logger_pid)
end
@doc """
handles EXIT messages from the GenEvent handler and restarts it
"""
def handle_info({:gen_event_EXIT, _handler, _reason}, logger_pid) do
{:ok, logger_pid} = start_handler(logger_pid)
{:noreply, logger_pid}
end
@doc """
starts a new handler listening for events on `logger_pid`
"""
defp start_handler(logger_pid) do
case GenEvent.add_mon_handler(logger_pid, LoggerHandler, []) do
:ok ->
{:ok, logger_pid}
{:error, reason} ->
{:stop, reason}
end
end
end
iex> {:ok, agent} = Agent.start_link(fn -> [1, 2, 3] end)
{:ok, #PID<0.65.0>}
iex> Agent.update(agent, fn (state) -> state ++ [4, 5] end)
:ok
iex> Agent.get(agent, &(&1))
[1, 2, 3, 4, 5]
iex> self
#PID<0.115.0>
iex> {:ok, agent} = Agent.start_link(fn -> [] end)
{:ok, #PID<0.123.0>}
iex> Agent.get(agent, fn(_) -> IO.inspect self end)
#PID<0.123.0>
iex> self
#PID<0.115.0>
Operations supported:
# They can be named!
iex> Agent.start_link(fn -> [1, 2, 3] end, name: Numbers)
{:ok, #PID<0.74.0>}
iex> Agent.get(Numbers, &(&1))
[1, 2, 3]
O(log n) or O(1) access times!
iex> table = :ets.new(:meetups, [:set, :protected])
8212
iex> :ets.new(:meetups, [:set, :protected, :named_table])
:user_lookup
iex> :ets.insert(:meetups, {"Kyiv Elixir", "awesome", ["Elixir"]})
true
iex> :ets.lookup(:meetups, "Kyiv Elixir")
{"Kyiv Elixir", "awesome", ["Elixir"]}
iex> :ets.match(:meetups, {:"$1", "awesome", :"_"})
[["Kyiv Elixir"]]
iex> :ets.delete(:meetups, "Kyiv Elixir")
true
iex> :ets.delete(:meetups)
true
Alex Rozumii
@brain-geek
FB: arozumiy