Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From Ruby to Elixir

From Ruby to Elixir

my talk at Sardines.rb (Lisbon Ruby meetup)

Daniel Serrano

August 13, 2019
Tweet

More Decks by Daniel Serrano

Other Decks in Programming

Transcript

  1. • why elixir? • historical context • quick intro •

    pipe operator • pattern-matching • processes • supervisors • phoenix • elixir in real life outline
  2. • elixir • preemptive Erlang VM • yielding lightweight processes

    • no locks, no mutexes, etc. • ranch, cowboy • functional, immutable • ruby • MRI relies on GIL • OS processes, threads • locks, mutexes, etc. • WEBrick, unicorn, puma, passenger, etc. • OO, mutable why elixir?
  3. historical context • Erlang (1986) • Ericsson (OSS 1998) •

    Ruby (1995) • Rails (2005) • F# (2005) • Clojure (2007) • Devise (2009) • Elixir (2009)
  4. quick intro • integers • 2, 0xcafe, 0b100, 10_000 •

    floats • 1.0, 3.1415, 6.02e23 • lists • [1, 2, 3], [head|tail] • map • %{one: “un”, two: “deux”} • atom • :foo, :me@home, :elixir • tuple • {:ok, 11, ‘hi'} • keyword list • [a: :foo, b: :bar] • binary • <<104, 101, 108, 108, 111>>, “hello”
  5. quick intro • functions • Enum.map/2, :erlang.localtime/0 • examples •

    IO.puts(“Hello World”) • Map.get(%{one: “un”}, :one) • struct(User, %{fname: “John”, lname: “Doe”}) # prints to stdout # returns “un” # returns a User struct # with first name “John”, # last name “Doe”
  6. quick intro defmodule User do defstruct [:fname, :lname] def full_name(%User{fname:

    fname, lame: lname}) do “#{fname} #{lname}” end end $> user = %User{fname: “John”, lname: “Doe”} $> User.full_name(user) “John Doe”
  7. pipe operator |> Enum.max(Enum.map(Enum.filter([1, 2, 3, 4, 5], fn x

    -> rem(x, 2) == 0 end), fn x-> x * 2 end)) • find max of double the values
  8. pipe operator |> Enum.max( Enum.map( Enum.filter( [1, 2, 3, 4,

    5], fn x -> rem(x, 2) == 0 end ), fn x-> x * 2 end ) )
  9. pipe operator |> [1, 2, 3, 4, 5] |> Enum.filter(fn

    x -> rem(x, 2) == 0 end) |> Enum.map(fn x -> x * 2 end) |> Enum.max() # 8
  10. pattern-matching def zero?(0), do: true def zero?(_), do: false zero?(0)

    zero?(3) zero?(“hello”) # true # false # false
  11. pattern-matching def started_at_text(%Task{started_at: nil}), do: “Not started” def started_at_text(%Task{started_at: time}

    = task) do
 “Started task-#{task.id} @ #{DateTime.to_string(time)}” end def state(%Task{started_at: nil, closed_at: nil}), do: :waiting def state(%Task{started_at: nil}), do: :canceled def state(%Task{closed_at: nil}), do: :in_progress
  12. elixir in real life • 1.5 billion page views per

    month • 200.000 concurrent users • resource intensive features • previously aggressive horizontal scaling • now 1/10th servers with low CPU usage
  13. elixir in real life • 100.000 concurrent users • previously

    Java • now Erlang, Go and Elixir • 10.000s to 100.000s users per machine
  14. elixir in real life • 11.000.000 concurrent users • 2.600.000

    concurrent voice users • 220 Gbps • 120 Mpps
  15. elixir in real life • media service handling millions of

    reqs/day • biometrics aggregator service handling 100.000s connections per day • average of 6 Kubernetes pods • cpu limits of 600m • mem limits of 512Mi