TDC2016SP - Trilha Programação Funcional
-
Upload
tdc-globalcode -
Category
Education
-
view
54 -
download
0
Transcript of TDC2016SP - Trilha Programação Funcional
Pedro Medeiros
Software Engineer @ Globo.com
/pedrosnk /pesnk
Escalando Elixir com OTP
O que vamos falar?
➔ Introdução a Elixir➔ Processos (modelo de concorrência)➔ OTP➔ GenServer, Supervisor, Application
Elixir
ElixirLinguagem funcional com suporte a meta-programação na maquina virtual Erlang.
ElixirLinguagem funcional com suporte a meta-programação na maquina virtual Erlang.
ElixirSample
defmodule Fibonacci do
def fib(0), do: 0
def fib(1), do: 1
def fib(n), do
fib(n-1) + fib(n-2)
end
end
IO.puts Fibonacci.fib(10)
Disclaimer
Disclaimer
Elixir não é apenas uma linguagem com syntax melhor que
Erlang.
1. Extensibilidade
2. Produtividade
3. CompatibilidadeElixir Design Goals
Polimorfismo de tipo e de modulos.Extensibilidade
Extensibilidade
Process
Estrutura 1 Estrutura 2
dado.value
Extensibilidade
Process
Process
Process
Call.here?
Extensibilidade
Process
Mensagem1 Mensagem2
JSON.decode
Extensibilidade
Process
Process
Process
Call.here?
Produtividade1. Mix2. Hex3. Docs4. Test
Great tooling
Produtividade
Mix
Produtividade
Hex
Produtividade
Docs
Produtividade
Test
Produtividade
Test
defmodule Fibonacci do
@doc """
Fibonacci
iex> Fibonacci.fib(10)
55
"""
def fib(0), do: 0
def fib(1), do: 1
def fib(n) do
fib(n - 1) + fib(n - 2)
end
end
Produtividade
Summary
$ mix new foobar$ cd foobar$ mix test$ mix hex.publish$ mix hex.docs
Compatibilidade Elixir and Erlang sitting on a tree
Compatibilidade
Elixir calls Erlang
Compatibilidade
Erlang calls Elixir
Processos 101
O modelo básico de concorrência
Processos
def ExpensiveProcess do
def loop do
receive do
{:operation, {sender, operation}} ->
operation = expensive_method(operation)
send sender, {:ok, operation}
loop()
:stop ->
:error
_ ->
loop()
end
end
end
ProcessosA P
B
C
ProcessosA P
B
C
ProcessosA P
B
C
ProcessosA P
B
C
OTP
Open Telecom Platform
OTP1. Building na Erlang VM2. Super Toolset para
construir aplicações tolerante a falha, escaláveis e distribuidas.
Open Telecom Platform
OTP
Qual problema resolve?
OTP
Switch
Switch
OTP
Server
Browser, Mobile, IoTsEndpoints
OTP
Open Telecom Platform
1. GenServer2. Supervisor3. Application
Behaviours
OTP
GenServer
defmodule MyServer do
use GenServer
def handle_call({:pop, _from, [item | state]}) do
{:reply, item, state}
End
def handle_cast({:push, item}, state) do
{:noreply, [item | state]}
End
def handle_info(:log, state) do
IO.puts("State of server is #{inspect(state)}")
{:noreply, state}
end
end
OTP
GenServer
defmodule MyServer do
use GenServer
def handle_call({:pop, _from, [item | state]}) do
{:reply, item, state}
End
def handle_cast({:push, item}, state) do
{:noreply, [item | state]}
End
def handle_info(:log, state) do
IO.puts("State of server is #{inspect(state)}")
{:noreply, state}
end
end
Sincronos
Assíncronos
Mensagem
OTP
Supervisor
Supervisor
S1 S2 S3
● Olha se o filho está vivo.● Gerencia filhos a partir de um
comportamento e estratégia● :one_for_one, :rest_for_all, :
rest_for_one
OTP
Supervisor
Supervisor
S1 S3
Estratégia :one_for_one
:one_for_one
Supervisor
S1 S3S1
OTP
Supervisor
Supervisor
S1 S3
Estratégia :rest_for_all
:rest_for_all
Supervisor
S1 S3S1
OTP
Supervisor
Supervisor
S1 S3
Estratégia :rest_for_one
:rest_for_all
Supervisor
S1 S3S1
OTP
Supervisor
defmodule MyServer.Supervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [])
end
def init([]) do
children = [
worker(MyServer, []),
worker(MyServer2, [])
]
supervise(children, strategy: :one_for_one)
end
end
OTP
Applicaton
Application é aonde todos os supervisors se inicializam.
● Código pequeno● Inicializa os Supervisors
que vivem “pra sempre”
OTP
Applicaton
OTP
Applicaton
defmodule Logger.App do
use Application
def start(_type, _args) do
import Supervisor.Spec
# ...
options = [strategy: :rest_for_one, name: Logger.
Supervisor]
children = [worker(GenEvent, [[name: Logger]]),
worker(Logger.Watcher, [Logger, Logger.Config, []],
[id: Logger.Config, function: :watcher]),
supervisor(Logger.Watcher, [Logger.Config, :handlers, []]),
worker(Logger.Watcher,
[:error_logger, Logger.ErrorHandler,
{otp_reports?, sasl_reports?, threshold},
:link],
[id: Logger.ErrorHandler, function: :
watcher])]
case Supervisor.start_link(children, options) do
{:ok, sup} ->
{:ok, sup, config}
{:error, _} = error ->
error
end
end
Lembram dele?
Server
Browser, Mobile, IoTsEndpoints
Obrigado
Recursos:
1. http://elixir-lang.org/2. https://hex.pm3. Programming Elixir Book4. The little Elixir and OTP Guidebook5. slideshare.net/pemedeiros