Live data from Hacker News

Elixir GenServer Explained

papercups.io

31–40 of 91 posts

Re: Elixir GenServer Explained

#31
post #10

Earlier quoted context omitted.

The sooner you start smacking people with tribal knowledge, the sooner many people start to back away slowly. I used to interview ex-coworkers. I don't do it as much anymore because it gets old/depressing and the answers tend not to change that much. If, for the purposes of thinking about turnover, you look at a former colleague as an 'aggrieved party', we are generally somewhere in the neighborhood of mediocre at ag…

What? GP's response is terse but not impolite, and explaining what an abbreviation means is a far cry from "smacking people with tribal knowledge", it's just table stakes explanation in a field which requires precision. The only reason modern computing got where it is today is by standing on the shoulders of giants. If we go back and re-litigate every naming decision of the past several decades just to make newcomers…

FWIW I thought the response was entirely fine and it wouldn't have occurred me to take offense at it.

(I actually googled what "gen" in "GenServer" was supposed to mean before posting, because I couldn't remember but knew it wasn't "generate", and couldn't find an answer, including in the docs for GenServer)

[EDIT] to clarify, I failed to find the answer in any of the Elixir docs for GenServer. Evidently I should have looked at Erlang.

Re: Elixir GenServer Explained

#32
post #5

Since these insert events are being buffered, what happens if the process dies? Are all of those inserts lost? I feel like Erlang/Elixir is designed to handle cases like this robustly, but it's not clear to me how this code avoids losing data when a process crashes, potentially up to 5s worth of updates!

The article touched on it briefly, but perhaps it wasn't clear.

If the process dies, the Supervisor invokes the `terminate/2` callback so you're still able to process events.

Here are the relevant lines: https://github.com/plausible/analytics/blob/b724def948d51a0f...

Keep in mind you need to trap exit signal to tell the supervisor to invoke the callback, as done so here: https://github.com/plausible/analytics/blob/b724def948d51a0f...

The erlang docs also mentions this: https://erlang.org/doc/design_principles/gen_server_concepts...

Re: Elixir GenServer Explained

#33
post #5

Since these insert events are being buffered, what happens if the process dies? Are all of those inserts lost? I feel like Erlang/Elixir is designed to handle cases like this robustly, but it's not clear to me how this code avoids losing data when a process crashes, potentially up to 5s worth of updates!

Short Answer - yes, data will be lost. THAT SAID - this is true of any buffering solution, it's why even the 'sync' style of request can still time out. Long Answer - What happens in any language where you batch stuff in memory? If the system breaks down, you lose that data. This isn't unique to Erlang/Elixir. There's a tradeoff that persistent storage is slower than memory, but it's persistent. So do you want to be…

> What happens in any language where you batch stuff in memory? If the system breaks down, you lose that data. This isn't unique to Erlang/Elixir.

A little over a decade ago I did a project using Erlang. My next project was using Ruby, and I was suddenly _horrified_ by the fact that I had no idea what would happen if the application crashed (and Ruby apps, at least in those days, crashed fairly often). Erlang/Elixir both forces you to think about these things, and gives you tools to address them, where many other languages (or their libraries) simply assume that we will stay on the happy path.

Of course, you can be very productive using languages that just ignore the possibility of very rare failures. Many successful systems work on the basis that sometimes shit just happens and maybe some data does get lost. But, after programming with Erlang or Elixir for a while, that situation starts to feel less acceptable!

Re: Elixir GenServer Explained

#34
This line in the opening paragraph really rubs me the wrong way:

> “I'm ashamed to say most of my Elixir education has been through trial and error, figuring things out as I go along“

This attitude is so prevalent in software as if we are all supposed to be divined with programming knowledge the moment our IDE spins up. In every other industry that’s exactly how you learn: Get your hands dirty, make mistakes, and fix them.

There’s a lot of things wrong with software engineering - harboring this attitude that self-taught learning is bad or shameful makes it unnecessarily worse

Great write-up otherwise

Re: Elixir GenServer Explained

#35

This line in the opening paragraph really rubs me the wrong way: > “I'm ashamed to say most of my Elixir education has been through trial and error, figuring things out as I go along“ This attitude is so prevalent in software as if we are all supposed to be divined with programming knowledge the moment our IDE spins up. In every other industry that’s exactly how you learn: Get your hands dirty, make mistakes, and fix…

Self-learning is one thing, but uninformed trial and error based on a lack of research is another beast entirely.

Re: Elixir GenServer Explained

#36

This line in the opening paragraph really rubs me the wrong way: > “I'm ashamed to say most of my Elixir education has been through trial and error, figuring things out as I go along“ This attitude is so prevalent in software as if we are all supposed to be divined with programming knowledge the moment our IDE spins up. In every other industry that’s exactly how you learn: Get your hands dirty, make mistakes, and fix…

Do you think that you can install a gas turbine the wrong way start it up and fix it later?

Re: Elixir GenServer Explained

#37

This line in the opening paragraph really rubs me the wrong way: > “I'm ashamed to say most of my Elixir education has been through trial and error, figuring things out as I go along“ This attitude is so prevalent in software as if we are all supposed to be divined with programming knowledge the moment our IDE spins up. In every other industry that’s exactly how you learn: Get your hands dirty, make mistakes, and fix…

There's a middle ground between (relatively) blind trial and error and being divinely granted insight. Deliberate reading of documentation (be it API, language standard, books, tutorials (better ones), etc.) lets you learn without just trying things or piecing a theory together from examples (underdocumented ones that don't explain the why of their choices).

Re: Elixir GenServer Explained

#38
> In particular, I was itching to learn more about handling concurrency in Elixir. This, of course, led me to GenServers.

Might be a nitpicking here, but GenServers aren't useful for concurrency. They just manage state, and only process one message at a time. If you're using this as a cache, your reads will be bottlenecked by however quickly the GenServer can handle the read requests.

Re: Elixir GenServer Explained

#39

This line in the opening paragraph really rubs me the wrong way: > “I'm ashamed to say most of my Elixir education has been through trial and error, figuring things out as I go along“ This attitude is so prevalent in software as if we are all supposed to be divined with programming knowledge the moment our IDE spins up. In every other industry that’s exactly how you learn: Get your hands dirty, make mistakes, and fix…

Do you think that you can install a gas turbine the wrong way start it up and fix it later?

Like most things, you build up to it.

You start software development with "Hello, world!" and then you do more, like getting input from the user, storing it in a variable, then eventually you're using classes and working with objects, then you're tying together a bunch of classes and working with APIs.

No one just "studied" how to create a gas turbine and wah-la, it was made. The entire process of literally everything was one learning exercise after another. We started by using rocks as tools. Here we are, having built better tools from experience and a lot of trial and error and fooling around with things.

Hell, Lego are the same exact idea.

Re: Elixir GenServer Explained

#40
post #26
post #21

Earlier quoted context omitted.

I'm talking about the name GenServer, not brobinson's response. There is the corollary: If we have not seen farther, it is because giants were standing on our toes. There's a huge degree of cognitive dissonance on these issues. Just because something had a reason in the past doesn't mean we have to keep doing it forever. Also "nobody understands" why people keep re-inventing wheels. It's not all hubris, at least not…

I've been using Elixir for 4 years, it pays my bills and I generally like it. GenServer could be a misleading name (it never occurred to me) but the real mess is the bag of handle this / handle that function names. They follow the conventions of Erlang [1] but Elixir's developers could have cast some syntactic sugar on top of it. The real name of those functions is in their first argument. handle_* is mostly noise. […

Syntactic sugar is of course another form of abstraction and so you have to balance developer ergonomics with that added complexity. As you point out, Elixir's `GenServer` is a fairly simple wrapper module over Erlang's own `gen_server`. As new versions of OTP are released, the maintainers of the Elixir language must also update their own abstractions over those underlying Erlang libraries. It also creates a niche disparity between Erlang and Elixir which some Erlang developers might find superfluous. Coming from Erlang, it's easy to appreciate the syntax of Elixir even if it means getting over some old habits. Perhaps changing the names of foundational parts of the standard library would be less appreciated by those already familiar with OTP, and feel as if the mental overhead is being shifted to those developers rather than simply being ameliorated for developers who are new to the platform.

Designing a programming language is hard, especially when building on top of a 35 year old language like Erlang. As is often the case: if engineers could change the past without breaking everything in the present, we would have already done it. :)

Post reply on HN