Hacker News new | ask | show | jobs
by lucidone 1298 days ago
Rails remains a best in class framework for web application development and ruby (in my opinion) a fantastic programming language (amazing object model + standard library).
1 comments

Sigh. As an old Rails hand myself - hell, I credit Rails for much of my tech career - I think I now have to disagree. Rails is great, indeed the best, for its use case, which is CRUD apps. That might still be enough. But what is expected of applications has changed over the years and Rails isn't really capable of meeting some of these new expectations, not alone anyway, and developers trying to implement them find themselves reaching for ever more kludges and workarounds and 3rd party software trying to fit, essentially, a square peg into a round hole.

Applications these days - well, a large number of them - need to be realtime. Server push. Websockets. Push notifications. Scheduled jobs. Long running background jobs. Calls into other services. Presence awareness. The list just goes on and on. And sure, you can somehow deal with all of this in Rails - hell, you can do anything in any language given enough time and effort - but you are absolutely going against the grain, and you're not using Rails anymore, you're using Rails + sidekiq + node + some other thing + xyz. I thought Rails was supposed to be the simple option?

Rails still might be the best choice, if you're sure your domain will never need to do anything long-lasting or concurrent. Internal admin apps or simple e-commerce would be good examples. But if it's going to be more than that then Rails might save you some time at the beginning only to bite you badly later on.

Phoenix 1.7 is out now and I basically recommend all rails developers to start learning it. It is going to be a bit of a learning curve, and it's not quite as lovable as ruby and its near-perfect syntax, but it is vastly more capable and is, IMO, the way forward. Frankly, I don't understand why it isn't much, much more popular.

I really have to disagree. My perspective is somebody that did some Rails work >10 years ago, followed the hype/money into Node.js and eventually Go, then ended up working in Rails again ~4 years ago.

In my experience a bog-standard vanilla Rails + Postgres setup provides all of the things you mentioned (except presence awareness, which is pretty tricky).

* Server push. Websockets. Push notifications. => ActionCable

* Scheduled jobs. Long running background jobs. => ActiveJob

* Calls into other services. => Pick your preferred HTTP library (or just use Net::HTTP)

All of the above have been part of Rails for years. The only additional Gem I would add is good_job to be the ActiveJob backend.

Now, if you start to bump up against what vertically scaling Postgres can handle, or you want some of the _additional features_ of a 3rd party dependencies (Redis, Sidekiq, Webpack, etc. etc.) you can easily add them, but it's realllly unnecessary for 99% of apps out there.

All those things you listed require additional background servers, redis, etc. In Elixir/Erlang, it's built into the runtime which is a huge advantage. And even with standard things like handling http requests in Elixir -absolutely smokes Ruby in terms of performance. This leads to real cost savings as well
Those built-ins that you are talking about are not as well rounded as a dedicated framework. These built-ins operate at a different operating model than running additional background servers. This typically means that everyone in the org needs to be an Elixir/Erlang expert instead of having experts in Redis, cloud native, ... For better or worse, this is likely a large obstacle for many orgs.

The argument for using Elixir/Erlang is also more difficult when you have large companies like Github and Shopify demonstrating that Ruby can scale.

EDIT:

Let's not forget that it's mostly the DB that slows CRUD apps down. Not the language or the framework.

No, they don't. You can absolutely run ActionCable with the postgres adapter in your main rails app server and require no additional services.

Edit: this is also why I mentioned GoodJob, it supports the full ActiveJob API (delays, retries, etc), even comes with a nice Web UI, and it only requires Postgres.

I'm using Quantum as my job runner in Elixir. Doesn't require even Postgres. Can't do that in Rails or other stacks:

https://github.com/quantum-elixir/quantum-core

^ obviously it won't fit every use case (where you need 100% durability) but for that there's Oban which is awesome:

https://getoban.pro

What is presence awareness?
I will just steal the first paragraph from https://hexdocs.pm/phoenix/presence.html, but you can read much more about it there.

> Phoenix Presence is a feature which allows you to register process information on a topic and replicate it transparently across a cluster. It's a combination of both a server-side and client-side library, which makes it simple to implement. A simple use-case would be showing which users are currently online in an application.

I see! Funny enough the app of the company I work for does this. The tech is simply running a stateful server behind the web server.
> Applications these days - well, a large number of them - need to be realtime

A large number of applications where and for what purpose? I think a large number of applications don't need to be realtime. The majority of applications exist that we never see, or frankly never know exist: SMBs that we've never heard of that are approaching (or have approached) the seven-figure revenue mark.

I do think, though, that a large number of developers have had their perception poisoned by this very crowd: that they need real-time, or a front-end framework, or plans for massive scale because they think they have to build the next Stripe or Twitter or FAANG-scale thing. Many of us, just like many applications, aren't going to scale like that, or hold those jobs.

The internet blossomed without real-time just fine. I think that it'd be just fine without it.

The funny thing is that I basically agree with you 100%. I constantly rail against, and mercilessly tease, companies building with microservices from day 1 or going with low-level high-performance languages like golang or rust before they even have a single customer "because FAANG does it". Monolith until you literally can't anymore. High level until you are forced to use something lower.

I did say that Rails is perfectly adequate for certain classes of applications. I guess the point I was trying to make, poorly as it turns out, is that for consumer applications at least, Rails is no longer the "sweet spot" and you hit up against its limitations earlier than ever and will, not might, will be forced to deploy ever more complex workarounds for basic functionality that you get out of the box in something like Phoenix. OK, forget websockets. How about scheduling a daily summary email? Daily reports? Anything other than a build-the-world, serve-request, tear-down-the-world HTTP query? Now you're running some separate thing and boom, there goes the simplicity.

I get you. I'm the "use boring tools" guy as well. But the tools have to be actually capable of doing the job, and the job has changed, well the kind of things I seem to be involved with have changed, and the Rails productivity "edge" lasts weeks at best.

> How about scheduling a daily summary email? Daily reports? Anything other than a build-the-world, serve-request, tear-down-the-world HTTP query?

This is a breeze in Ruby. You really think Ruby devs don't do periodic jobs? There are many many good battle tested solutions for that in Ruby.

And they're all inferior to what Elixir can do out of the box without ductaping on 3rd party tools. Running other services like Redis is not only not a breeze, it's an additional expenses and thing to monitor.
I assume most big Elixir apps use Redis or something similar anyway for its speed and reliability (it can periodcally persist for instance) instead of saving everything in memory. Redis is widely used with a huge community support and you usually don't want to lose all your background job info (you don't have to use an actual DB, but Redis seems like a good compromise for many companies). If you don't want Redis there are background job gems for Postgres/MySQL etc. As for monitoring - in our current micro service world adding or removing Redis is peanuts. You have so much stuff to monitor you need strong monitoring, and usually a whole team dedicated to set it up. Doing that for Ruby or Elixir is negligble. I'd even say Ruby is more straightforward to monitor for devops people than Elixir (that's from stories I've read, not an expert on that).

There's plenty of real issues with Ruby (and with Elixir), but what you're arguing here is simply non issues imo.

> low-level high-performance languages like golang

This is the first time I've ever seen Go called a low level high performance language. Maybe compared to Python or Ruby I guess, which is fair.

> Go called a low level high performance language

Ah yeah, was generalising somewhat. You're right, it's perhaps a "mid" level language. Maybe even high level in areas it is intended for, such as channel tooling, etc. Regardless, it's much more verbose than true high-level languages such as Ruby and I would not consider it a good choice for a startup unless they were specifically writing actual infrastructure code.

Regardless - it's certainly implicated in the cargo cult of "dozens of golang microservices all talking to each other in a combinatory explosion of GRPC" antipattern i've seen startups succumb to before. One of them ran out of runway with less than 10 actual customers, after spending 18 months building an MVP that would "scale".

Maybe I can propose a new law: "If you have more microservices than you have customers, you are scaling prematurely".

Just replace microservices with erlang processes?
> How about scheduling a daily summary email? Daily reports?

Forgive me if I'm wrong (I don't know Phoenix that well), but don't you need some external library like Exq do perform background jobs? How is Phoenix+Exq different from Rails+Sidekiq?

You don't need to run a jobs server, the language itself handles the processes. Most people use a library but the work still happens in the language runtime. And you can even build your own on top of supervisors, genserver, etc.

  Frankly, I don't understand why it isn't much, much more popular.
It's been a few years since I walked away from Elixir and Phoenix for recreational projects so I've forgotten the finer points. The two things that bothered me the most were that a.) Erlang treats BSD as a second class citizen and b.) I got the sense that there was a lot of cargo culting going on. Getting an informed answer felt like it was just that much more difficult than with say Ruby.

Professionally, as an ops monkey, I wouldn't want to be on the hook for supporting an Erlang or Elixir app. There's definitely a chicken-egg problem and I'd worry about finding coworkers who would be comfortable with Elixir, but there are also simply far too many moving parts. Like. Yeah okay channels are cool, in-place upgrades are cool, and a well disciplined team could make good use of them but to me that all sounds like a lot of very tempting footguns. All of a sudden I'm not just supporting an app, I'm supporting an entire runtime on top of Linux. I'd much rather deal with a single binary like e.g. go or rust provide, and I'd much rather not deal with Erlang processes and whatnot.

That said the language itself is great. At the time I started dicking around with Phoenix I was working with a guy who was making a big push to use clojure for internal tooling. I liked the Elixir syntax which felt like a great mashup of Ruby and Clojure.

> All of a sudden I'm not just supporting an app, I'm supporting an entire runtime on top of Linux. I'd much rather deal with a single binary like e.g. go or rust provide, and I'd much rather not deal with Erlang processes and whatnot

(Not trying to be argumentative.)

We have been quite ok just deploying our elixir stuff as containers per anything else (seems this is even common for go services - even though just the binary is enough theoretically). Connecting a cluster of beam-containers is not really any different to a cluster of go-containers, etc. Possibly when you last used Phoenix it didn't have built in releases (portable, compiled packaged dir + binary) - and a Dockerfile generator.

I likely lack the perspective you have, but I think you can discard a lot of the beams "classical" deployment story for something that's no different to Rails/Go/etc and I don't think you lose anything besides hot-code-upgrades which I think aren't really that needed in todays multi-node infrastructure. A container going down isn't any different to a raw beam node going down so its much-for-muchness.

Have no idea why you're being downvoted. You can not like someone's opinion but if its reasonably argued I don't see why you should downvote.

Cargo cult as you said...

Elixir has better concurrency we get it. It also has a tiny market share and other issues of its own (steep learning curve, functional programming, having to dive into Erlang sometimes etc etc). By choosing Elixir you trade one problem with a bunch of other problems and most CTOs don't really care for the tradeoff Elixir offers. Community, learning curve and availability of libraries are way more important than how many pods you have to run. I'd go with Python/Java/PHP/Ruby/Node and many other stacks before going with Elixir and I think many people agree with me.
Subjective, but I don't think it's fair to say Elixir has a steep learning curve. It's quite readable, well documented, and has a good Repl so you can experiment. You can even view documentation in the Repl.

It might depend which languages you already know, but if you've done modern JavaScript a lot of the function elements will be familiar.

I'd argue basics of Elixir are simpler than Ruby. The tricky part is OTP concepts but you can use Elixir without knowledge of that.

This is a wonderful resource:

https://joyofelixir.com/toc.html

When I first started learning Rails at a company, my ex-boss hired me even if I had 0 experience in RoR, 0 industrial exp in web development. I came from a c++ guy. So jobs were plenty. Now companies who want to hire Elixir devs don't have that mindset, none! (practically), this is why elixir adoption stuck.