Slides of Ulisses Almeida, Elixir Developer at The Coingaming Group, at Elixir Club Ukraine, Kyiv, 28.09.2019
Next conference - http://www.elixirkyiv.club/
Description of presentation
GenServers plays a central role in Elixir OTP applications.
However, when you overuse it, it can become an anti-pattern and introduce bottlenecks in your system.
In this talk you'll learn:
* What's a GenServer
* When GenServer can harm
* GenServer FOMO (fear of missing out)
* How Elixir ecosystem get you covered
After this talk, you'll understand how putting a GenServer in the wrong place can slowdown in your entire system.
You'll understand how the Elixir frameworks and libraries enable you to have reliable concurrency applications.
You'll feel no shame of being an Elixir developer and never had to write yourself a GenServer.
Follow us on social networks @ElixirClubUA and #ElixirClubUA
Announce and materials from conf - https://www.fb.me/ElixirClubUA
News - https://twitter.com/ElixirClubUA
Photo and free atmosphere - https://www.instagram.com/ElixirClubUA
*Organizer’s channel - https://t.me/incredevly
2. Summary
■ What is GenServer?
■ How can you harm your app by putting
GenServer in the wrong place?
■ Why do people think that they need a
GenServer all the time?
■ Considerations before writing a GenServer
9. Why Tallinn? !
★ Low renting costs
★ Free transportation for
residents
★ E-estonia 💻
★ Safe
★ Low taxes
★ Accessible travels
๏ Cold and Dark ☃
๏ Estonian is the first
language !
๏ Russian is the second
language $
๏ Eastern/nordic culture
is different
11. Who
We Are
The Coingaming Group are the
crypto gaming pioneers who
operate the world’s leading bitcoin
gaming and betting brands.
https://coingaming.io/
20. GenServer
■ Useful for: Client-Server
relationship
■ Keep state
■ Execute code
asynchronously
(handle_cast)
■ Synchronously too
(handle_call)
■ Provide tracing and error
reporting features
■ Can be supervised
A process with a
powerful set of
features
21. Shades of a GenServer
■ Agent
■ Task
■ Task.Supervisor
■ Supervisor
■ DynamicSupervisor
■ GenStage
■ …
36. GenServer checklist
■ Model state accessed by multiple
processes
■ Run multiple tasks concurrently
■ Communicate between servers
■ Gracefully handle clean startup and exit
concerns
https://pragprog.com/book/tvmelixir/adopting-elixir
37. CalculatorServer checklist
❌Model state accessed by multiple
processes
❌Run multiple tasks concurrently
❌Communicate between servers
❌Gracefully handle clean startup and exit
concerns
https://pragprog.com/book/tvmelixir/adopting-elixir
38. CalculatorServer has no
reason to be a GenServer
A GenServer must
never be used for
code organization
purposes
https://hexdocs.pm/elixir/GenServer.html
GenServer to organize
domain, business
contexts
GenServer to model
runtime properties
of your system
40. I have been working with Elixir for ~3 years
■ I hardly often write a GenServer
■ I mostly wrote GenServers in recruitment
processes and for fun
■ I deleted some unnecessary production
GenServers
■ I know excellent developers that never
wrote one
47. Users -> App checklist
✔ We need to handle multiple users
connections concurrently
✔ Other processes might send messages to
that connection
✔ We have to handle connections openings
and closings gracefully.
49. However…
■ Each user’s request
has a process that runs
concurrently
■ You can focus on the
functional part
■ (functional part?
functional
programming 🥁)
Phoenix and
Cowboy handles
that for you
51. App & Database checklist
✔Databases are an external service
communication
✔We have to provide a limited number of
connections to a lot of processes
✔These connections have to run concurrently
✔We need to handle connection openings
and closings gracefully
53. However…
■ Ecto supports a pool of
connections
■ Ecto handle that
concurrently
■ Work here is also done
■ You can focus on the
business 💰Ecto handles that
for you
55. App & Other Services checklist
✔ Usually, we communicate through a network
✔ We might need to offer a pool as a backpressure
mechanism to not bring down weak services
✔ These pools have to run multiple requests
concurrently
✔ Gracefully handle connections opening and
closings
57. However…
■ You can start simple,
for example, no pool
■ Watch out for big
timeouts
■ Circuit breakers can
help you out
■ Choose the libraries,
and you can focus on
features
Hackney and other
libraries handles
that for you
59. Not everything is stored in SQL databases
■ Examples: caching,
session, users
presence
■ Transient or Persistent?
■ How big will it be?
■ Write vs Read
✔ This data will be
accessible by multiple
processes
63. However…
■ A better abstraction reveals
intention, for example,
Cachex vs GenServer + ETS
■ How does your deploy
work?
■ Shutdown and booting the
app will lose GenServer/
ETS data
■ Redis for the rescue
■ Discuss the right tool for
the job, compare the
tradeoffs
You might want to
use a specific
abstraction.
67. However…
■ You would need an
Erlang cluster to run a
global GenServer
■ What happens with
network partition?
■ Use your database
power
■ Transactions or locks in
the database
■ Discuss with your team,
compare the tradeoffs
You environment
might not allow.
a.k.a Heroku
69. Tasks outside of a request/response cycle
■ Welcome e-mail
■ Push notifications
■ Scheduled tasks
✔ We need to spawn or
schedule these
background tasks
✔ We need to run the
background tasks
concurrently
71. However…
■ GenServers aren’t
persistent
■ Shutting downs might
lose data
■ RabbitMQ has persistent
queues
■ Libraries that use Redis
to store the jobs and
their arguments
■ Discuss with your team,
compare the tradeoffs
How to handle the
failures? Do you
need some
persistence?
72. We covered a lot
of considerations before
“let's write a GenServer” decision
And they are still not
over
86. References
■ Adopting Elixir - https://pragprog.com/book/tvmelixir/adopting-
elixir
■ Spawn or not spawn - https://www.theerlangelist.com/article/
spawn_or_not
■ You may not need a GenServer - https://pragtob.wordpress.com/
2019/04/24/you-may-not-need-genservers-and-supervision-trees
■ GenServer (Elixir Docs) - https://hexdocs.pm/elixir/GenServer.html
■ Elixir discussion forum - https://elixirforum.com/t/you-may-not-
need-genservers-and-supervision-trees/12947