Is it wrong to use Agent.stop/3 on a GenServer?

I’m new to Elixir, but having hammered out some code on a practical project and also going through the excellent elixir-lang.org getting started tutorials. I love the flexibility and the “just get it done” feel of the language and platform.

Coming from a more strictly OOP world though, I was surprised when I could call Agent.stop(Foo.bar) where Foo.bar is actually a GenServer. As GenServer actually has its own GenServer.stop/3 what is the harm in misusing the stop/3 for Agents on a different ‘class’?

They both seem to work interchangeably on each other.

Thanks

Let me tell you a secret: Agent.stop/3 secretly calls GenServer.stop/3 (and does nothing else).

I assume it has been added to the Agent module as well to make sure that someone building an Agent (which for many people is the first introduction to the OTP concepts) has enough using just the Agent module, rather than also needing to look in other modules for (common) tasks.

3 Likes

A minor-but-important nitpick: in code like Agent.stop(Foo.Bar), Foo.Bar is the name of a GenServer not the GenServer itself - Foo.Bar itself is a shorthand for the atom :"Elixir.Foo.Bar", but that atom doesn’t have to correspond to any actual module.

4 Likes

I want to just reiterate this because it’s really important (I’m also pretty n00bish to Elixir). Do not conflate processes with modules. Modules just hold functions that processes call. Calling self() in a module will return the pid of the process it’s running in, it has nothing to do with the module itself. This really tripped me up at first (coming from OO) and was hard to internalize, even after I understood it.

4 Likes

Sorry, @al2o3cr, I probably shouldn’t have tagged you in agreement as opposed to replying to you—That would have made more sense :sweat_smile:

Very good point, and yes, this was something I had to internalize though the elixir-lang.org section on Agents and GenServers explained it very well with the 'where the Process.sleep(5000) will actually delay… client or server, though the decoupling was still a bit confusing.

Super useful thanks!
Now I know where to poke in the source code as well! I was relying only on iex ‘h GenServer.stop’ and ‘h Agent.stop’ and since they returned (slightly) different doc specs and didn’t mention each other there was no hierarchy implied… hence the question.

1 Like