Jeeves - something that would be nice to have directly in Elixir

https://github.com/pragdave/jeeves Is great abstraction over the Genserver. It covers real life usecases for singleton and pooled Genservers which is better abstraction to build upon. Having something like this in language core would help standardize solutions based in this approach.

7 Likes

While it’s a very nice library, I personally feel that language core should be minamlist while still useful. Having used languages that do have dumping grounds for functionality, I appreciate leanness in the core.

The reason for this is simple: approaches evolve and change … new implementations that build on pre-existing ideas can provide significant improvements, but may not be API compatible. Putting more and more, especially higher level functionality, into the core makes it harder and harder to allow that evolution to occur.

At the same time, keeping a small core also makes the solution more useful in a greater number of scenarios (“Elixir is not just for web apps”, i.e.) and keeps maintenance manageable. Which typically means higher quality.

Looking at Phoenix, Ecto, etc. it is evident that not having those things in the “core” does not prevent general (though not universal) adoption/standardization.

Having a curated “Best Of Elixir” would be fantastic as a resource however, to accomplish what you seek: adoption of great ideas, standardizing of solutions. (Those “awesome” lists are not that …)

I do think that over time, as Elixir gets more and more popular, something will need to be done about the typical module explosion that other successful module-based ecosystems have experienced. Personally I think it is part cultural (“One liners are not candidates for modules”, “Reinventing wheels is counterproductive”, …) and part community assist (e.g. via curation efforts) and perhaps just a pinch of technology (e.g. if mix hex.search would provide more information on usage / popularity / curation …).

That said, yeah, Jeeves looks pretty dang neat :slight_smile:

2 Likes

You are right in general. But sometimes minimalistic means that many people implement the same solutions using different libraries and final app ends as a big depencency hell. The right balance is required. Jeeves took my attention as Genserver concept is very nice for me but too low level for most usecases. For example Genserver as single process, where all casts and calls are serialized to queue, is performance problem for slow codes (external api calls, database calls and many, many others) So some pooling mechanism beeing part of language would be nice as all developers can build upon this and not using poolboy with different versions as dependency …

I think it was Dave Thomas talking in one of his presenations about too many dependencies in Rails world and that he can see this comming to Elixir/Phoenix … as a bad thing.

1 Like

The main reason, for me, against including this library in core is that it is extremely macro heavy with a huge amount of indirection. I have a hard time understanding the code, and I have some experience with elixir doing it professionally for almost 2 years now. I would expect this task to be even more daunting for beginners.

I feel like this is one of those libraries that makes things easy, but unfortunately not simple.

Additionally the code produced by the library is hard to test, since all the processes it starts are named from inside the start_link function - it’s impossible to test the servers concurrently and you need to manually reset their state between the tests. Starting a new process per test is usually an approach that works much better - you can run your tests concurrently and no cleanup is needed.

1 Like

@michalmuskala you are right, my intention was not to include Jeeves code into core, but adopt this concept and add similar abstraction to language …

1 Like

Please note I’ve moved this to the Elixir Chat section as #your-libraries-projects:libraries section is for threads about your own personal libraries.

1 Like

So, imho, the challenge specifically with putting pooling into the core is that one size does not fit all. GenServer gets close (99.9%+) to “fitting all sizes”, but pooling is not nearly so uniform.

Distributed vs local? For running jobs or persisting state or limiting resource consumption (e.g. connections to a DB)? Unlike a “process that responds to messages, sync or async, that also carries state” is pretty generic, pooling is less so. It is more widely useful than other topics we could pick, but there isn’t a one-size-fits-all solution to pooling processes.

Yes, one could extend a pooling solution with more modes and options, but would it not be better to have focused solutions?

(Side note: one thing I don’t like about Jeeves, tbh: it provides a form of pooling … but also named processes with state … why?)

There’s also the problem of giving someone a hammer in the default toolkit: they use it to bang on everything as if it were a nail. If pooling was a part of the core language, I expect it would get used in places pooling is not the best option.

Given the learning curve around processes and things like GenServer, I suspect the added cognitive load of also having pooling right in there would push the adoption cost even a bit higher. It’s nicer imho to grow into such things rather than have them sitting in the default toolbox with the new developer wondering just how to use which tool and when.

I know not everyone agrees with this POV :slight_smile: … it’s just what I’ve seen/experienced over the years.

“Too many dependencies” can be undesirable for a few reasons. One is that they are a deployment burden, but I think that Elixir has a good path forward there. One issue can’t be solved only through better/faster foundations is the cost of choice: having to sort through what does exist, what is worth using, how to use the new beast …

I really really hope that Elixir’s culture develops to favor “fewer, higher quality” solutions than “lots of different ways of doing things so we can explore diversity”. I’d much rather see 1-2 options in widespread usage for each topic area, and I hope that idiomatic Elixir takes hold across the libraries that achieve widespread usage so that learning to use library X is natural and easy because we are used to the same patterns as seen in libraries A…V.

I have been involved in communities with a strong sense of “how things are done” and ones where … it was less so. And when there is a shared understanding of how things are done, there is greater consistency leading to lower learning curves and less diversity-for-the-sake-of-not-using-someone-else’s-library.

Curation of libraries would really also help one quickly / easily identify (and therefore make selecting dependencies easier/cheaper) the ones that are mature, actively maintained (not always the same as actively developed), idiomatic, etc. This is something that hex.pm could really, really help with if it evolved from being “only” a package warehouse and grew into a package economy (and I don’t mean that in the monetary sense).

1 Like