4 ms·
I'm curious about the experience of having taught a senior dev GenServers so early on. I guess it depends on what they are working on, but I think for most peo
by dnautics 5y ago
I'm curious about the experience of having taught a senior dev GenServers so early on. I guess it depends on what they are working on, but I think for most people (senior devs included) GenServers are YAGNI -- I have not once written a genserver for my current job, the senior might be tempted to be clever and use GenServers as code organization or as a circumvention to write stateful code, a la "objects" because GenServers are rather close to Alan Kay's original objects.
But I guess that's what code review is for!
- zinclozenge 5y agoThe temptation is there, but AFAIK most learning materials are good to call out that processes are for concurrency needs, and a genserver is an abstraction on top of that to help with certain things, like synchronization.
- akoutmos 5y agoIn my day to day work I don't write many GenServers either and I think that's a good thing. Like any tool, they can be overused and abused. It is best to stick to modules and pure functions until you really need to pull the stateful lever. To that point, GenServers as an abstraction are super powerful and when applicable, are an amazing tool. For example, being able to control the initialization of a supervision trees using :ignore in the init callback can be handy to run DB migrations as part of the application startup. Or when used in combination with a registry it can be useful to hold on to user data in a GenServer and access it atomically across your cluster.
- slezakattack 5y agoAs a seasoned Erlang developer, it's really foreign to me that people can go so far as to never need a GenServer since they are everywhere in Erlang. Have you had any experience with ramping up an Erlang engineer to use Elixir? After interviewing an Elixir dev for an Erlang position, it was interesting that so much of what they used in their day-to-day abstracted away the components of OTP and the Beam. Didn't really have a firm grasp of supervision trees, process linking vs monitoring, etc.
- dnautics 5y agoThere's so much you can use instead of GenServer. Elixir gives you Task for one-offs, which is a superior abstraction over proc_lib, and has seamless integration with OTP things like supervision trees, which you will have to roll by hand and probably mess up if you use proc_lib. For just stateful data, ets is much better performance-wise than a GenServer (with the tradeoff being complexity in understanding matchspecs and the like), and Agent is much simpler for dumb state and leads to better code (though I basically never use Agent). Honestly, I think the GenServer behaviour is awful (not GenServers, themselves, they are great), because it does not engender writing well-organized code. Dave Thomas' empex talk about it is really eye-opening and you will understand the internalized pain. (I don't like his specific recommendations, and I think the ship has sailed on Elixir reimagining how GenServers are organized). So yeah. My philosophy is don't write GenServers, unless you are really sure you need them (like maybe collaborative state for games; to wrap a stateful communication protocol, like http tcp, or an application layer over udp; or to to model something IRL or remote, e.g. browser state as in liveview, or as I have in a previous gig, qemu VM state). And even for some of these you're probably better of with a gen_statem or the like. > supervision trees, process linking vs monitoring you still need to understand these to use Task correctly, or gen_statem, but those are really advanced topics. It's crazy, but you can get really really far without those (even if it's not, strictly speaking best practice), and it's not like once you learn about them it's hard to change your code to start using those correctly.