elbasti

elbasti

Genserver: should we prefer thin callbacks or thin interface functions?

Stylistic question:

When writing a genserver module, we often write a set of interface functions and (of course) the callbacks. Assume that there is some business logic (data manipulation of the received message, spawning multiple processes, etc).

Should that business logic be placed in the interface function, leaving a “thin” callback, or the other way around?

Especially if some of the business logic involves calling other interface functions, spawning tasks, etc.

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

This question to me goes far beyond style, because the performance characteristics and failure modes are super different.

Let me first make sure I am capturing your question properly. You’re comparing these situations

# logic in the interface function
def some_action(server, arg) do
  computed_value = # fun business logic
  GenServer.call(server, {:some_action, arg, computed_value})
end

vs

# logic in the callback function
def handle_call({:some_action, arg}, state) do
  computed_value = # fun business logic
  {:reply, blah}
end

Style here is the absolute last consideration. Code executed in the interface function is executed in the caller process whereas code executed in the callback is executed in the genserver. The primary question at hand is whether or not it needs to access or have atomic control over the genserver state. If so it has to go in the callback. If it doesn’t, then you’d likely favor the client pid to avoid bottlenecking the genserver, since the genserver can only handle 1 message at a time.

Each case has very different failure modes too. If an exception is raised in def some_action then this just crashes the caller pid, but the genserver remains. If you raise an exception in handle_call then this crashes both the genserver, and any currently linked caller pids.

11
Post #2
derek-zhou

derek-zhou

It is not a style question but an architecture question. The point of a GenServer is to serialize and enforce state transition. So anything that need to be serialized should be in the callbacks. Anything that don’t should be in the interface function.

Where Next?

Popular in Discussions Top

PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
owaisqayum
I have a sample string sentence = "Hello, world ... 123 *** ^%&*())^% %%:>" From this string, I want to only keep the integers, ...
New
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 13924 124
New
Qqwy
I would like to spark a discussion about the static access operator: .. For whom does not know: it is used in Elixir to access fields of...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
tomekowal
Hey guys! I want to create a toy project that shows a chart of temperature over time and updates every 5 seconds. I feel LiveView is per...
New
acrolink
How does the two languages compare when it comes to server side application development? Any experiences or ideas? Thank you.
New
AstonJ
Can you believe the first professionally published Elixir book was published just 8 years ago? Since then I think we’ve seen more books f...
New
slashdotdash
Phoenix Live View is now publicly available on GitHub. Here’s Chris McCord’s tweet announcing making it public.
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

We're in Beta

About us Mission Statement