Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Aprendizados de um projeto Elixir OTP
Search
Amanda
May 26, 2019
Technology
650
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Aprendizados de um projeto Elixir OTP
Elixir Brasil 2019
Amanda
May 26, 2019
More Decks by Amanda
See All by Amanda
Lessons Learned From an Elixir OTP Project
amandasposito
2
110
SOLID - Dependency inversion principle
amandasposito
0
100
Como concorrência funciona em Elixir?
amandasposito
1
240
Programação Funcional & Elixir
amandasposito
3
140
Ecto, você sabe o que é ?
amandasposito
4
250
Novidades no Rails 5
amandasposito
0
110
Rails Engines & RSpec
amandasposito
0
250
Elixir e Phoenix
amandasposito
3
600
Elixir em 5 minutos
amandasposito
1
110
Other Decks in Technology
See All in Technology
AI Made Us Faster at Solving the Wrong Problems
marceloancelmo
0
140
KanaAI
shreyas1009
0
140
生成AIと進める探索的データ分析(2026.10.03 第122回Tokyo.R勉強会)
tatamiya
2
1.2k
猫でもわかるKiro Web
kentapapa
1
160
Amazon Bedrock Agents ClassicからAmazon Bedrock AgentCoreへ移行した際、ガードレール設定が2箇所に割れた話
matsunobu
0
170
『GOエコノミー 』(相乗りサービス) におけるスペック駆動開発
mot_techtalk
1
220
LLM機能を自作して分かるSnowflake Cortex AIの強み
nayuts
0
210
覗いてみよう 関数型ビジュアル言語×2Dグラフィックスの世界
yohyamasaki
0
170
Databricksメトリクスビューはじめてのもくもく会
taka_aki
0
170
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
2
320
2026-09-26 Platform Engineering Kaigi 2026 インフラとアプリの境界線と委譲の設計 / Drawing the Infra and App Line
masasuzu
0
590
メルカリにおけるAI時代の高速プロトタイピング基盤「Arca」
ryotarai
18
14k
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
10k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
550
WENDY [Excerpt]
tessaabrams
14
40k
We Are The Robots
honzajavorek
0
380
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
66k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
520
Evolving SEO for Evolving Search Engines
ryanjones
0
300
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Building AI with AI
inesmontani
PRO
1
1.3k
Ethics towards AI in product and experience design
skipperchong
2
410
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
350
Transcript
Aprendizados de um projeto Elixir/OTP
→ amandasposito.com → speakerdeck.com/amandasposito → linkedin.com/in/amandasposito
careers.plataformatec.com.br
Disclaimer
Como foi começar em um projeto Elixir, vindo de outra
linguagem?
None
None
None
Como utilizar o ferramental da linguagem a seu favor?
None
Lidar com banco de dados se tornou muito mais comum
Preloads
None
SELECT * FROM Courses; SELECT * FROM Users WHERE course_id
= ? SELECT * FROM Users WHERE course_id = ? SELECT * FROM Users WHERE course_id = ?
None
Repo.all from c in Course, preload: [:users]
Ecto tem muitas features interessantes que podem te ajudar no
dia-a-dia
→ Changesets
→ Changesets → Schemas
→ Changesets → Schemas → Ecto.Multi
→ Changesets → Schemas → Ecto.Multi → etc.
Lidando com tabelas gigantescas
Qualquer coisa que fossemos alterar no banco era difícil
None
None
use Mix.Task
defmodule Mix.Tasks.Echo do use Mix.Task @impl Mix.Task def run(_args) do
Mix.shell.info "Hello World" end end
Saber analisar a performance é muito importante
Explain Analyze
EXPLAIN ANALYZE SELECT "courses"."id", "courses"."data" FROM "courses" INNER JOIN "users"
ON ("courses"."user_id" = "users"."id") WHERE "users".account_id = 4500000;
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
None
None
http://blog.plataformatec.com.br/2019/02/migrations-in-databases-with-large-amount-of-data/
Tabelas ETS
"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
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
None
Nesse momento não tinhamos muita visão da quantidade de dados
Velocidade x Quantidade de itens
A estimativa estava em 76GB de consumo de memória por
máquina
None
Tabelas ETS não possuem muitas opções de otimização como o
Redis
None
São como se fossem um Hash direto na memória
Consomem a memória disponível da aplicação
None
https://moz.com/devblog/moz-analytics-db-free
None
Testes
Doctest != Test
None
Sua aplicação está se comunicando com o mundo exterior, e
agora?
None
None
None
None
Como fazer para stubar/mockar uma requisição?
Bypass
None
setup do bypass = Bypass.open {:ok, bypass: bypass} end
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
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
def fetch(url \\ "https://api.twitter.com") do {:ok, response} = HTTPoison.get("#{url}/1.1/search/tweets.json") Jason.decode!(response.body)
end
Quando usar bypass?
Código que precisa realizar requests HTTP
None
Mox
None
None
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
http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/
GenServer
Como testar processos?
Testar Callback de GenServer não é uma boa prática
None
GenServer.cast
GenServer.call
https://devonestes.herokuapp.com/unit-tests-in-elixir-part-2
Quais os problemas mais comuns encontrados?
→ 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?
A probabilidade do código ficar complexo diminui
Mas os problemas ainda existem
Muitos dos problemas que vemos em OOP reconhecemos em FP
→ Funções muito grandes
→ Funções muito grandes → Funções difíceis de testar
→ Funções muito grandes → Funções difíceis de testar →
Mudanças simples precisam ser feitas em vários lugares
→ Funções muito grandes → Funções difíceis de testar →
Mudanças simples precisam ser feitas em vários lugares → Feature Envy
→ 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
→ 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
→ 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
https://youtu.be/eldYot7uxUc
None
Contexts
A idéia é definir limites entre diferentes módulos da aplicação
Com o passar do tempo e a necessidade de interação
com vários schemas
Os contextos podem ficar maiores do que deveriam
Preste atenção para não manter código ortogonal ao contexto, no
contexto
Mantenha queries próximas de seu schema
A exceção são queries que lidam com mais de um
schema
http://devonestes.herokuapp.com/a-proposal-for-context-rules
None
Umbrella Projects
Dentro de um Umbrella app os apps deveriam acessar arquivos
uns dos outros?
É uma maneira de organizar seu código
None
None