The document discusses the history and capabilities of the Erlang programming language. It provides examples of core Erlang concepts like processes, message passing, and the OTP framework. Key points made include:
- Erlang has had over 30 years of development and provides reliable, fault-tolerant distributed programming through its use of lightweight processes and message passing.
- Examples demonstrate basic Erlang features like spawning processes, sending messages, and linking processes to trap exits.
- OTP provides tools like GenServers and supervisors to build robust, supervised applications from actor-like processes.
- Erlang's model of isolated, message-passing processes allows it to scale applications to millions of concurrent
23. LOW LATENCY
http://yarivsblog.blogspot.com.br/2008/05/erlang-vs-scala.html
Scala has two types of Actors: thread-based and event based. Thread based actors execute in heavyweight OS threads. They never block each other, but they don't
scale to more than a few thousand actors per VM. Event-based actors are simple objects. They are very lightweight, and, like Erlang processes, you can spawn millions
of them on a modern machine. The difference with Erlang processes is that within each OS thread, event based actors execute sequentially without preemptive
scheduling. This makes it possible for an event-based actor to block its OS thread for a long period of time (perhaps indefinitely).
24. começo de novembro
Rackspace 15 GB I/O v1 - these machines have 15GB RAM and 4 cores. Rackspace kindly let us use 3 of these servers for our benchmarks free of charge.
OnMetal I/O which had 128GB RAM and showed 40 cores in htop.
25. começo de novembro
Rackspace 15 GB I/O v1 - these machines have 15GB RAM and 4 cores. Rackspace kindly let us use 3 of these servers for our benchmarks free of charge.
OnMetal I/O which had 128GB RAM and showed 40 cores in htop.
29. “Since cut-over of the first nodes in British Telecom's network
in January 2002 only one minor fault has occurred, resulting in
99.9999999% availability.”
“The network performance has been so reliable that there is
almost a risk that our field engineers do not learn maintenance
skills.”
Bernt Nilsson - director of Ericsson’s Next Generation Systems program
44. Matching
a = 20
defmodule Teste do
def teste do
a = 40
IO.puts("Hello #{a}")
end
end
IO.puts(a)
a = 20
^a = 40
[a, b, c] = [a, 2, 3]
{:ok, message} = {:ok, "world"}
{:ok, [hello: message]} = {:ok, [hello: "world"]}
45. Matching
a = 20
defmodule Teste do
def teste do
a = 40
IO.puts("Hello #{a}")
end
end
IO.puts(a)
a = 20
^a = 40
[a, b, c] = [a, 2, 3]
{:ok, message} = {:ok, "world"}
{:ok, [hello: message]} = {:ok, [hello: "world"]}
47. Call by pattern
defmodule Greeting do
def hello([name: name]) do
"Hey, #{name}"
end
def hello([lastname: lastname]) do
"Hello, Mr #{lastname}"
end
end
Greeting.hello(name: "Fabio")
Greeting.hello(lastname: "Akita")
48. Call by pattern
defmodule Greeting do
def hello([name: name]) do
"Hey, #{name}"
end
def hello([lastname: lastname]) do
"Hello, Mr #{lastname}"
end
end
Greeting.hello(name: "Fabio")
Greeting.hello(lastname: "Akita")
53. Processes
Process.list
defmodule Foo do
def counter(n) do
receive do
{:read, from} ->
send(from, n)
counter(n + 1)
end
end
end
pid = spawn(fn -> Foo.counter(2) end)
list = Enum.map((1..500_000), fn n ->
spawn(fn -> Foo.counter(n) end)
end)
54. Processes
Process.list
defmodule Foo do
def counter(n) do
receive do
{:read, from} ->
send(from, n)
counter(n + 1)
end
end
end
pid = spawn(fn -> Foo.counter(2) end)
list = Enum.map((1..500_000), fn n ->
spawn(fn -> Foo.counter(n) end)
end)
59. Observer/Schedulers
defmodule Foo do
def counter(n) do
receive do
{:read, from} ->
send(from, n)
counter(n + 1)
end
end
end
list = Enum.map((1..100_000), fn n ->
spawn(fn -> Foo.counter(n) end)
end)
Enum.each(list, fn pid -> Process.exit(pid, :kill) end)
defmodule Repeat do
60. Observer/Schedulers
defmodule Foo do
def counter(n) do
receive do
{:read, from} ->
send(from, n)
counter(n + 1)
end
end
end
list = Enum.map((1..100_000), fn n ->
spawn(fn -> Foo.counter(n) end)
end)
Enum.each(list, fn pid -> Process.exit(pid, :kill) end)
defmodule Repeat do
62. GenServer Simple
defmodule Stack do
use GenServer
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
end
end
{:ok, pid} = GenServer.start_link(Stack, [:hello])
GenServer.call(pid, :pop)
GenServer.cast(pid, {:push, :world})
GenServer.cast(pid, {:push, :blabla})
GenServer.call(pid, :pop)
63. GenServer Simple
defmodule Stack do
use GenServer
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
end
end
{:ok, pid} = GenServer.start_link(Stack, [:hello])
GenServer.call(pid, :pop)
GenServer.cast(pid, {:push, :world})
GenServer.cast(pid, {:push, :blabla})
GenServer.call(pid, :pop)
64. defmodule Stack do
use GenServer
# Public API
def pop(server), do: GenServer.call(server, :pop)
def push(server, item), do: GenServer.cast(server, {:push, item})
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
end
end
{:ok, pid} = GenServer.start_link(Stack, ["John"])
Stack.push(pid, "Woo")
65. defmodule Stack do
use GenServer
# Public API
def pop(server), do: GenServer.call(server, :pop)
def push(server, item), do: GenServer.cast(server, {:push, item})
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
end
end
{:ok, pid} = GenServer.start_link(Stack, ["John"])
Stack.push(pid, "Woo")
66. GenServer Kill
defmodule Stack do
use GenServer
def start_link(state, opts []) do
GenServer.start_link(__MODULE__, [state], name: __MODULE__)
end
def pop, do: GenServer.call(__MODULE__, :pop)
def push(item), do: GenServer.cast(__MODULE__, {:push, item})
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
67. GenServer Kill
defmodule Stack do
use GenServer
def start_link(state, opts []) do
GenServer.start_link(__MODULE__, [state], name: __MODULE__)
end
def pop, do: GenServer.call(__MODULE__, :pop)
def push(item), do: GenServer.cast(__MODULE__, {:push, item})
# Callbacks
def handle_call(:pop, _from, [head|tail]) do
{:reply, head, tail}
end
def handle_cast({:push, item}, state) do
{:noreply, [item|state]}
68. Supervisor - Restart
defmodule StackSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [])
end
def init([]) do
children = [
worker(Stack, ["hello"])
]
supervise(children, strategy: :one_for_one)
end
end
StackSupervisor.start_link
69. Supervisor - Restart
defmodule StackSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [])
end
def init([]) do
children = [
worker(Stack, ["hello"])
]
supervise(children, strategy: :one_for_one)
end
end
StackSupervisor.start_link
85. Javascript /
shared mutable global state
Blocking Event Loop
Rust /
Low Level
Async in progress
No coroutines
Go
Suture
(OTP Clone)
goroutines sem ID
shared mutable state
static signatures
Scala
Akka
(OTP Clone)
shared mutable state
static signatures
Clojure Pulsar / Quasar
Almost Erlang-like Process
JVM limitations
Go http://www.jerf.org/iri/post/2930
Scala http://yarivsblog.blogspot.com.br/2008/05/erlang-vs-scala.html
Clojure http://blog.paralleluniverse.co/2013/05/02/quasar-pulsar/
Scala has two types of Actors: thread-based and event based. Thread based actors execute in heavyweight OS threads. They never block each other, but they don't
scale to more than a few thousand actors per VM. Event-based actors are simple objects. They are very lightweight, and, like Erlang processes, you can spawn millions
of them on a modern machine. The difference with Erlang processes is that within each OS thread, event based actors execute sequentially without preemptive
scheduling. This makes it possible for an event-based actor to block its OS thread for a long period of time (perhaps indefinitely).