PubNative Tracker
Andrew Djoga
Elixir is what would happen if Erlang, Clojure and
Ruby somehow had a baby and it wasn't an
accident.
Devin Torres
open source enthusiast
Immutability
animals = ["capybara", "apple", "lemur"]
List.delete(animals, "apple")
#=> ["capybara", "lemur"]
animals
#=> ["lion", "table", "bear"]
High-order functions
double = fn(i) -> i * 2 end
Enum.map([1, 2, 3], double)
#=> [2, 4, 6]
Pattern matching
[first, second, _] = [
:virginia,
:singapore,
:ireland,
]
first
#=> :virginia
second
#=> :singapore
Pattern matching
list = [1, 2, 3]
[1 | tail] = list
tail
#=> [2, 3]
[2 | _] = list
** (MatchError) no match of right hand side
value: [1, 2, 3]
Collections
Enum.any?(["foo", "bar", “hi"],
fn(s) -> len(s) == 2 end)
#=> true
File.read("path/to/unknown/file")
#=> {:error, "reason"}
map = %{:foo => "bar", :hello => "hi"}
map[:foo]
#=> “bar"
Functions
def square([]), do: []
def square([head | tail]) do
[head * head | square(tail)]
end
square([1, 2, 3])
#=> [1, 4, 9]
Enum.map([1, 2, 3], fn(x) -> x * x end)
#=> [1, 4, 9]
Composition
defmodule Math do
def sum(a, b) do
a + b
end
end
Math.sum(1, 2)
#=> 3
Concurrency
lightweight
isolation
message passing
Concurrent processes with no data sharing
provide a strong measure of fault isolation.
A software error in a concurrent process
should not influence processing in the other
processes in the system.
creator of Erlang
Joe Armstrong
Based on its designated behavior, the actor responds
to incoming messages by send new messages,
spawn new actors and/or changing its future behavior.
Each actor has its own mailbox and isolated state.
Supervisor
children = [
supervisor(Stats.Supervisor),
supervisor(Queue.KafkaSupervisor),
worker(Queue.SQSWorker, [period, []]),
supervisor(Queue.Supervisor),
supervisor(Cache.DBSupervisor),
Plug.Adapters.Cowboy.child_spec(:http, Router, [],
[port: port])
]
supervise(children,
strategy: :one_for_one,
max_restarts: 10,
max_seconds: 1
)
Worker
def handle_cast(:receive, state) do
case :sqs.receive(state.queue) do
[] -> Logger.info("no messages")
messages -> to_kafka(messages)
end
{:noreply, state}
end
def terminate(reason, _) when reason == :normal, do: :ok
def terminate(reason, state) do
Logger.error("#{reason}: #{inspect state}")
:ok
end
tooling
IEx
iex(1)> Weather
...(1)> |> where(city: "Berlin")
...(1)> |> order_by(:temp_lo)
...(1)> |> limit(10)
...(1)> |> Repo.all
Mix
mix new my_app
compile
test
deps.get
ExUnit
test "decodes a base64 without padding chars" do
assert Token.urlsafe_decode64("YWJjZA") == "abcd"
assert Token.urlsafe_decode64("YWJjZA=") == "abcd"
assert Token.urlsafe_decode64("YWJjZA==") == "abcd"
end
➜ tracker mix test test/tracker/api/token_test.exs --trace
Tracker.API.TokenTest
* decodes a base64 without padding chars (8.1ms)
* decodes a base64 in the URLEncoding mode defined in RFC 4648 (0.01ms)
* fixes a token with a double question mark (0.01ms)
* decrypts a token (15.2ms)
* returns error with a broken token (14.8ms)
Finished in 0.1 seconds (0.09s on load, 0.03s on tests)
5 tests, 0 failures
Type Specifications
@spec network(integer) :: {String.t, String.t} | :not_found
def network(id) do
case :ets.lookup(:db_networks, id) do
[{^id, name, url}] -> {name, url}
_ -> :not_found
end
end
Dialyzer is a static analysis tool that identifies software
discrepancies such as type errors, unreachable code,
unnecessary tests, etc in Erlang / Elixir applications.
$ iex --name console@127.0.0.1 --remsh tracker@127.0.0.1
etop
Erlang Top is a tool for presenting information about Erlang
processes similar to the information presented by "top" in
UNIX.
erlang.processes()
Returns a list of process identifiers corresponding to all
the processes currently existing on the local node.
erlang.memory()
Returns a list with information about memory dynamically
allocated by the Erlang emulator.
Built-In Term Storage
ETS tables are implemented as BIFs in the ets
module.
The main design objectives ETS had was to
provide a way to store large amounts of data in
Erlang with constant access time and to have
such storage look as if it were implemented as
processes in order to keep their use simple and
idiomatic.
http://learnyousomeerlang.com
http://elixir-lang.org
http://erlang.org/doc/design_principles/users_guide.html
http://ninenines.eu/docs/en/cowboy/1.0/guide

PubNative Tracker

  • 1.
  • 3.
    Elixir is whatwould happen if Erlang, Clojure and Ruby somehow had a baby and it wasn't an accident. Devin Torres open source enthusiast
  • 4.
    Immutability animals = ["capybara","apple", "lemur"] List.delete(animals, "apple") #=> ["capybara", "lemur"] animals #=> ["lion", "table", "bear"]
  • 5.
    High-order functions double =fn(i) -> i * 2 end Enum.map([1, 2, 3], double) #=> [2, 4, 6]
  • 6.
    Pattern matching [first, second,_] = [ :virginia, :singapore, :ireland, ] first #=> :virginia second #=> :singapore
  • 7.
    Pattern matching list =[1, 2, 3] [1 | tail] = list tail #=> [2, 3] [2 | _] = list ** (MatchError) no match of right hand side value: [1, 2, 3]
  • 8.
    Collections Enum.any?(["foo", "bar", “hi"], fn(s)-> len(s) == 2 end) #=> true File.read("path/to/unknown/file") #=> {:error, "reason"} map = %{:foo => "bar", :hello => "hi"} map[:foo] #=> “bar"
  • 9.
    Functions def square([]), do:[] def square([head | tail]) do [head * head | square(tail)] end square([1, 2, 3]) #=> [1, 4, 9] Enum.map([1, 2, 3], fn(x) -> x * x end) #=> [1, 4, 9]
  • 10.
    Composition defmodule Math do defsum(a, b) do a + b end end Math.sum(1, 2) #=> 3
  • 11.
  • 12.
    Concurrent processes withno data sharing provide a strong measure of fault isolation. A software error in a concurrent process should not influence processing in the other processes in the system. creator of Erlang Joe Armstrong
  • 13.
    Based on itsdesignated behavior, the actor responds to incoming messages by send new messages, spawn new actors and/or changing its future behavior. Each actor has its own mailbox and isolated state.
  • 14.
    Supervisor children = [ supervisor(Stats.Supervisor), supervisor(Queue.KafkaSupervisor), worker(Queue.SQSWorker,[period, []]), supervisor(Queue.Supervisor), supervisor(Cache.DBSupervisor), Plug.Adapters.Cowboy.child_spec(:http, Router, [], [port: port]) ] supervise(children, strategy: :one_for_one, max_restarts: 10, max_seconds: 1 )
  • 15.
    Worker def handle_cast(:receive, state)do case :sqs.receive(state.queue) do [] -> Logger.info("no messages") messages -> to_kafka(messages) end {:noreply, state} end def terminate(reason, _) when reason == :normal, do: :ok def terminate(reason, state) do Logger.error("#{reason}: #{inspect state}") :ok end
  • 16.
  • 17.
    IEx iex(1)> Weather ...(1)> |>where(city: "Berlin") ...(1)> |> order_by(:temp_lo) ...(1)> |> limit(10) ...(1)> |> Repo.all
  • 18.
  • 19.
    ExUnit test "decodes abase64 without padding chars" do assert Token.urlsafe_decode64("YWJjZA") == "abcd" assert Token.urlsafe_decode64("YWJjZA=") == "abcd" assert Token.urlsafe_decode64("YWJjZA==") == "abcd" end ➜ tracker mix test test/tracker/api/token_test.exs --trace Tracker.API.TokenTest * decodes a base64 without padding chars (8.1ms) * decodes a base64 in the URLEncoding mode defined in RFC 4648 (0.01ms) * fixes a token with a double question mark (0.01ms) * decrypts a token (15.2ms) * returns error with a broken token (14.8ms) Finished in 0.1 seconds (0.09s on load, 0.03s on tests) 5 tests, 0 failures
  • 20.
    Type Specifications @spec network(integer):: {String.t, String.t} | :not_found def network(id) do case :ets.lookup(:db_networks, id) do [{^id, name, url}] -> {name, url} _ -> :not_found end end Dialyzer is a static analysis tool that identifies software discrepancies such as type errors, unreachable code, unnecessary tests, etc in Erlang / Elixir applications.
  • 21.
    $ iex --nameconsole@127.0.0.1 --remsh tracker@127.0.0.1 etop Erlang Top is a tool for presenting information about Erlang processes similar to the information presented by "top" in UNIX. erlang.processes() Returns a list of process identifiers corresponding to all the processes currently existing on the local node. erlang.memory() Returns a list with information about memory dynamically allocated by the Erlang emulator.
  • 22.
    Built-In Term Storage ETStables are implemented as BIFs in the ets module. The main design objectives ETS had was to provide a way to store large amounts of data in Erlang with constant access time and to have such storage look as if it were implemented as processes in order to keep their use simple and idiomatic.
  • 23.