$30 off During Our Annual Pro Sale. View Details »

Aprendizados de um projeto Elixir OTP

Aprendizados de um projeto Elixir OTP

Elixir Brasil 2019

Amanda

May 26, 2019
Tweet

More Decks by Amanda

Other Decks in Technology

Transcript

  1. SELECT * FROM Courses; SELECT * FROM Users WHERE course_id

    = ? SELECT * FROM Users WHERE course_id = ? SELECT * FROM Users WHERE course_id = ?
  2. EXPLAIN ANALYZE SELECT "courses"."id", "courses"."data" FROM "courses" INNER JOIN "users"

    ON ("courses"."user_id" = "users"."id") WHERE "users".account_id = 4500000;
  3. Gather (cost=847239.21..2458486.98 rows=2 width=16) (actual time=35048.574..45161.127 rows=2 loops=1) Workers Planned:

    2 Workers Launched: 2 -> Hash Join (cost=846239.21..2457486.78 rows=1 width=16) (actual time=32820.132..45130.374 rows=1 loops=3) Hash Cond: (courses.user_id = users.id) -> Parallel Seq Scan on courses (cost=0.00..1040678.17 rows=45193617 width=16) (actual time=0.044..29710.148 rows=33333333 loops=3) -> Hash (cost=846239.20..846239.20 rows=1 width=8) (actual time=8318.392..8318.392 rows=1 loops=3) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Seq Scan on users (cost=0.00..846239.20 rows=1 width=8) (actual time=819.773..8318.380 rows=1 loops=3) Filter: (account_id = 4500000) Rows Removed by Filter: 49999999 Planning time: 0.421 ms Execution time: 45169.333 ms
  4. "These provide the ability to store very large quantities of

    data in an Erlang runtime system, and to have constant access time to the data." — Erlang Documentation
  5. def hello do opts = [ :set, :named_table, :public, read_concurrency:

    true ] table_name = :elixir_brasil :ets.new(table_name, opts) for n <- 1..100 do :ets.insert(table_name, {n, "Key #{n}"}) end end
  6. test "fetch/1 returns and formats tweets", %{bypass: bypass} do response

    = Jason.encode!([%{"text" => "Elixir Brasil 2019"}]) Bypass.expect(bypass, fn conn -> assert "/1.1/search/tweets.json" == conn.request_path assert "GET" == conn.method Plug.Conn.resp(conn, 200, response) end) tweets = TwitterClient.fetch("http://localhost:#{bypass.port}") assert tweets == [%{"text" => "Elixir Brasil 2019"}] end
  7. test "fetch/1 returns and formats tweets", %{bypass: bypass} do response

    = Jason.encode!([%{"text" => "Elixir Brasil 2019"}]) Bypass.expect(bypass, fn conn -> assert "/1.1/search/tweets.json" == conn.request_path assert "GET" == conn.method Plug.Conn.resp(conn, 200, response) end) tweets = TwitterClient.fetch("http://localhost:#{bypass.port}") assert tweets == [%{"text" => "Elixir Brasil 2019"}] end
  8. Mox

  9. test "messages/0 lists all messages from the timeline" do TwitterMock

    |> expect(:fetch, fn -> [%{"text" => "Olá mundo"}] end) assert Timeline.messages() == {:ok, 1} end https://github.com/amandasposito/mox_example
  10. → Tudo que eu aprendi em OOP, vou jogar fora

    em funcional? → Como eu organizo meu código? → Todos os problemas que eu tinha em OOP, somem em funcional? → E esse tal de Context? Comé qui usa?
  11. → Funções muito grandes → Funções difíceis de testar →

    Mudanças simples precisam ser feitas em vários lugares
  12. → Funções muito grandes → Funções difíceis de testar →

    Mudanças simples precisam ser feitas em vários lugares → Feature Envy
  13. → Funções muito grandes → Funções difíceis de testar →

    Mudanças simples precisam ser feitas em vários lugares → Feature Envy → Contextos com muitas linhas
  14. → Funções muito grandes → Funções difíceis de testar →

    Mudanças simples precisam ser feitas em vários lugares → Feature Envy → Contextos com muitas linhas → Acoplamento
  15. → Funções muito grandes → Funções difíceis de testar →

    Mudanças simples precisam ser feitas em vários lugares → Feature Envy → Contextos com muitas linhas → Acoplamento