Anúncio
Anúncio

Mais conteúdo relacionado

Similar a "Elixir of Life" - Dev In Santos(20)

Mais de Fabio Akita(20)

Anúncio

"Elixir of Life" - Dev In Santos

  1. ELIXIR OF LIFE http://www.efeitmusic.com/efeitimages/Elixeroflife.jpg
  2. Fabio Akita ELIXIR OF LIFE http://www.efeitmusic.com/efeitimages/Elixeroflife.jpg
  3. @akitaonrails
  4. 0 1,000,000,000 2,000,000,000 3,000,000,000 4,000,000,000 5,000,000,000 6,000,000,000 7,000,000,000 8,000,000,000 1965 1970 1975 1980 1985 1990 1995 2000 2005 2010 2015 2020 Intel1Processors1Transistor1Count Intel 4004 10 µm Intel 80386 Pentium 0.8 µm Itanium 2 Six-core Xeon 7400 8-core Itanium Poulson 32 nm 18-core Xeon Haswell-E5 22 nm 15-core Xeon Ivy Bridge-EX Duo-core + GPU Core i7 Broadwell-U 14 nm Apple A7 Apple A8 Apple A8X 20 nm
  5. Deveríamos estar em 9Ghz 16nm transistors quantum tunneling leakage, 1-3nm http://en.wikipedia.org/wiki/Quantum_tunnelling
  6. EVENTOS!
  7. Node + Express (8 x 200)
  8. Node + Express (8 x 200)
  9. Elixir + Phoenix (8 x 200)
  10. Elixir + Phoenix (8 x 200)
  11. Node + Express (1 x 10 + sleep(1))
  12. Node + Express (1 x 10 + sleep(1))
  13. Elixir + Phoenix (2 x 400 + sleep(1000))
  14. Elixir + Phoenix (2 x 400 + sleep(1000))
  15. 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).
  16. 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.
  17. 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.
  18. CASES
  19. “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
  20. http://www.erlang.org/download/armstrong_thesis_2003.pdf
  21. BÁSICO …
  22. iex --sname fabio --cookie secret_token iex --sname akita --cookie secret_token Node.list Node.ping(:"akita@MacBook-Pro") defmodule Greeting do def say do IO.puts "CALLED" "Hello World from #{Node.self}" end end :rpc.call(:"fabio@MacBook-Pro", Greeting, :say, []) iex --name fabio@192.168.1.4 --cookie secret_token iex --name akita@192.168.1.4 --cookie secret_token
  23. iex --sname fabio --cookie secret_token iex --sname akita --cookie secret_token Node.list Node.ping(:"akita@MacBook-Pro") defmodule Greeting do def say do IO.puts "CALLED" "Hello World from #{Node.self}" end end :rpc.call(:"fabio@MacBook-Pro", Greeting, :say, []) iex --name fabio@192.168.1.4 --cookie secret_token iex --name akita@192.168.1.4 --cookie secret_token
  24. PEER-TO-PEER NETWORKING
  25. 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"]}
  26. 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"]}
  27. PATTERN MATCHING
  28. 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")
  29. 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")
  30. CALL BY PATTERN
  31. Spawn self send(self, :hello) flush send(self, :hello) receive do :hello -> IO.puts("hello") end defmodule Bar do def say do receive do {:ok, message} -> IO.puts("Hello #{message}") say end end end
  32. Spawn self send(self, :hello) flush send(self, :hello) receive do :hello -> IO.puts("hello") end defmodule Bar do def say do receive do {:ok, message} -> IO.puts("Hello #{message}") say end end end
  33. PROCESS (GREEN THREAD) Green Thread = Co-Rotina que pode ser suspensa 2000 reduções single thread por core/scheduler 1 run-queue
  34. 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)
  35. 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)
  36. ASYNCHRONOUS EXCEPTIONS ESTADO IMUTAVEL SEM ESTADO GLOBAL
  37. ASYNCHRONOUS EXCEPTIONS ESTADO IMUTAVEL SEM ESTADO GLOBAL
  38. Trap Exits (http://eddwardo.github.io/elixir/links/2015/11/04/links-in-elixir/) defmodule Foo do def counter(n) do receive do {:read, from} -> send(from, n) counter(n + 1) {:bla} -> raise "I'm a bug!" end end end pid = spawn(fn -> Foo.counter(2) end) Process.alive?(pid) Process.link(pid) Process.exit(pid, :kill) pid = spawn(fn -> Foo.counter(2) end)
  39. Trap Exits (http://eddwardo.github.io/elixir/links/2015/11/04/links-in-elixir/) defmodule Foo do def counter(n) do receive do {:read, from} -> send(from, n) counter(n + 1) {:bla} -> raise "I'm a bug!" end end end pid = spawn(fn -> Foo.counter(2) end) Process.alive?(pid) Process.link(pid) Process.exit(pid, :kill) pid = spawn(fn -> Foo.counter(2) end)
  40. 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
  41. 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
  42. ACTORS!
  43. 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)
  44. 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)
  45. 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")
  46. 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")
  47. 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]}
  48. 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]}
  49. 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
  50. 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
  51. SUPERVISOR TREE (supervisor - supervisees/workers)
  52. OTP (Open Telecom Platform)
  53. Phoenix - Observer Applications - Micro Services
  54. Phoenix - Observer Applications - Micro Services
  55. MICRO “YOCTO” SERVICES (Micro > Nano > Pico > Femto > Atto > Zepto > Yocto)
  56. • Map, Structs, Records, Comprehensions
  57. • Map, Structs, Records, Comprehensions • Testable Docs
  58. • Map, Structs, Records, Comprehensions • Testable Docs • TypeSpecs/Behaviors
  59. • Map, Structs, Records, Comprehensions • Testable Docs • TypeSpecs/Behaviors • Agents/Tasks/GenEvent
  60. • Map, Structs, Records, Comprehensions • Testable Docs • TypeSpecs/Behaviors • Agents/Tasks/GenEvent • Sigils/Macros/DSLs
  61. • Map, Structs, Records, Comprehensions • Testable Docs • TypeSpecs/Behaviors • Agents/Tasks/GenEvent • Sigils/Macros/DSLs • ETS/DETS/Mnesia
  62. 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).
  63. “quase” …
  64. Erlang: DONE! (30 anos)
  65. APRENDENDO
  66. become@codeminer42.com OBRIGADO
Anúncio