Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016

Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016

7c12adb8b5521c060ab4630360a4fa27?s=128

Plataformatec

June 22, 2016
Tweet

Transcript

  1. @georgeguimaraes / @plataformatec ELIXIR. PROGRAMAÇÃO FUNCIONAL E PRAGMÁTICA

  2. consulting and software engineering

  3. None
  4. None
  5. ESTAMOS CONTRATANDO!
 http://plataformatec.workable.com

  6. NOSSA GERAÇÃO TEM UM PROBLEMA. Desenvolvedores web tem que lidar

    com concorrência. Não há escapatória.
  7. CONCORRÊNCIA. Capacidade de lidar com várias coisas (ao mesmo tempo,

    ou serialmente).
  8. PARALELISMO. Capacidade de fazer várias coisas ao mesmo tempo.

  9. CONCORRÊNCIA. Websockets, HTTP2, Alta quantidade de requests, demanda instável.

  10. None
  11. None
  12. THREADS E EVENT LOOP. Modelos primitivos para lidar com concorrência.

  13. “what makes multithreaded programming difficult is not that writing it

    is hard, but that testing it is hard. It’s not the pitfalls that you can fall into; it’s the fact that you don’t necessarily know whether you’ve fallen into one of them. ”
  14. None
  15. — ROBERT VIRDING “Any sufficiently complicated concurrent program in another

    language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.”
  16. PLATAFORMA ELIXIR. Erlang and OTP, now with modern tooling.

  17. None
  18. 30 anos

  19. None
  20. None
  21. Switch

  22. Switch

  23. Switch

  24. Switch

  25. Switch Switch

  26. Switch Browser Endpoint Server

  27. — ELIXIR DEVELOPER “We stand in the shoulders of giants”

  28. # #MYELIXIRSTATUS

  29. DOCUMENTAÇÃO DE ALTO NÍVEL. Documentação ruim é bug.

  30. None
  31. FERRAMENTAL EMBUTIDO. Hex, Mix, ExUnit.

  32. None
  33. None
  34. LINGUAGEM FUNCIONAL.

  35. IMUTABILIDADE. “Isso muda tudo”

  36. list = [1, 2, 3] DoSomethingWith(list) list = [4, 5,

    6] AnotherThingWith(list)
  37. NÃO TENHO LOOPS!

  38. defmodule Fibonacci do def calc(0), do: 0 def calc(1), do:

    1 def calc(n), do: calc(n-1) + calc(n-2) end Fibonacci.calc(10) # => 55
  39. MAS, E COMO FAZER UM CONTADOR? Não é possível mudar

    o conteúdo de uma variável????
  40. defmodule Counter do def start(value) do receive do :increment ->

    start(value + 1) {:get, pid} -> send(pid, value) end end end
  41. defmodule Counter do def start(value) do receive do :increment ->

    start(value + 1) {:get, caller} -> send(caller, value) end end end pid = spawn(fn -> Counter.start(10) end) send(pid, :increment) send(pid, :increment) send(pid, :increment) send(pid, {:get, self}) flush # => 13
  42. shell

  43. shell Counter.start(10) spawn

  44. shell 11 increment

  45. shell 12 increment

  46. shell 13 increment

  47. shell 13 :get, self 13

  48. defmodule Counter do def start(value) do receive do :increment ->

    start(value + 1) {:get, caller} -> send(caller, value) end end end pid = spawn(fn -> Counter.start(10) end) send(pid, :increment) send(pid, :increment) send(pid, :increment) send(pid, {:get, self}) flush # => 13
  49. ACTOR MODEL. 1. Enviar mensagens para outros atores; 2. Criar

    novos atores; 3. Especificar o comportamento para as próximas mensagens.
  50. Sequential code

  51. Sequential code elixir

  52. Sequential code elixir

  53. elixir

  54. elixir

  55. None
  56. None
  57. FAULT-TOLERANT. DISTRIBUTED. O objetivo não era concorrência.

  58. Switch Switch

  59. CONCORRÊNCIA É UM CASO DE DISTRIBUIÇÃO. Tá distribuído, mas apenas

    em uma máquina.
  60. elixir

  61. elixir

  62. elixir

  63. defmodule MyApp do use Application def start(_type, _args) do import

    Supervisor.Spec, warn: false children = [ supervisor(Playfair.Repo, []), worker(Playfair.Mailer, []), worker(Playfair.FileWriter, []), ] opts = [strategy: :one_for_one, name: Playfair.Supervisor] Supervisor.start_link(children, opts) end end
  64. None
  65. defmodule MyApp.Mixfile do use Mix.Project def application do [mod: {Playfair,

    []}, applications: [:phoenix, :phoenix_html, :cowboy, :logger, :gettext, :phoenix_ecto, :postgrex, :calendar]] end defp deps do [ {:phoenix, "~> 1.1.4"}, {:postgrex, ">= 0.0.0"}, {:phoenix_ecto, "~> 2.0"}, {:phoenix_html, "~> 2.4"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.10"}, {:cowboy, "~> 1.0"}, {:credo, "~> 0.3", only: [:dev, :test]}, {:basic_auth, "~> 1.0"}, {:csv, "~> 1.2.4"}, {:scrivener, "~> 1.0"}, {:scrivener_html, "~> 1.0"}, {:calendar, "~> 0.13"} ] end end
  66. ERROS ACONTECEM. Let it crash.

  67. ESTADO CORRUPTO PODE OCORRER. Let it crash. O processo vai

    voltar com um estado limpo.
  68. MAS SERÁ QUE FUNCIONA MESMO?

  69. http://blog.whatsapp.com/index.php/ 2012/01/1-million-is-so-2011/ 2 million connections on a single node

  70. Intel Xeon CPU X5675 @ 3.07GHz 24 CPU - 96GB

    Using 40% of CPU and Memory
  71. None
  72. None
  73. MICROSERVIÇOS EM UM MUNDO ELIXIR. Precisamos sempre de APIs HTTP?

  74. elixir

  75. node@srv2 node@srv1 elixir

  76. None
  77. None
  78. ONDE APRENDER?.

  79. None
  80. None
  81. None
  82. None
  83. None
  84. consulting and software engineering

  85. DÚVIDAS? 
 @plataformatec
 @georgeguimaraes

  86. @elixirlang / elixir-lang.org