Hacker News new | ask | show | jobs
by ZoFreX 5064 days ago
I'm actually quite excited about this, because I think it makes a lot of sense for this to be in Rails, for a couple of reasons.

First of all, there aren't really any decent solutions for the problem in Ruby. There's a few projects with great potential, but nothing really mature - when I needed to do this, I went with cramp.in, which hasn't been updated in over 6 months now sadly. Node.js would unequivocally have been the better tool for the job, but I didn't want to learn Javascript or Node for this one-off.

Secondly, even if there were mature Ruby equivalents to Node.js, or no impediment to me using Node, I can still see a lot of benefit to doing this in Rails. Personally I think it makes sense to be able to send events down to the clients and hook into the same models and business code you already have in place in the Rails app. (For certain use-cases, for example a project that's in Rails, is mostly a "regular" web app, but you want to give live updates for certain model changes, such as messages, ticket changes, new blog posts, whatever - obviously if the app is totally oriented around live functionality then node would probably be a smarter choice)

(I apologise for using the term "Node.js" as if its another web framework, I know that's not entirely accurate but I don't know enough about it to write more accurately!)

2 comments

> First of all, there aren't really any decent solutions for the problem in Ruby.

Even ignoring other frameworks, Rails has supported streaming through various APIs since at least the 2.x days.

In Rails 2, you would pass a Proc to the render method giving direct access to the response.

Rails 3 changed the API to any Enumerable assigned to self.response_body, as described in the article.

Rails 4 gets yet another API. It may be arguably cleaner, but the end functionality remains the same as it has always been.

> First of all, there aren't really any decent solutions for the problem in Ruby.

Uh? Rack has supported streaming since the beginning, and Sinatra has had special support on top of that since 1.3.

> Secondly, even if there were mature Ruby equivalents to Node.js

http://rubyeventmachine.com/

> I can still see a lot of benefit to doing this in Rails.

Don't dismiss the drawbacks. Such as self-DOS-ing. Your Rails application can only have as many clients total as you have workers if they all keep a permanent connection.

"Why your web framework should not adopt Rack API" by José Valim

http://blog.plataformatec.com.br/2012/06/why-your-web-framew...

"This blog post is an attempt to detail the limitations in the Rack/CGI-based APIs that the Rails Core Team has found while working with the streaming feature that shipped with Rails 3.1 and why we need better abstractions in the long term."

Broken middlewares won't be any less broken now that before.
They are less broken now. The Rails team put a lot of effort into fixing them in the past three releases.
I was more meaning top to bottom, although I confess I never looked into the feasibility of just rolling my own thing with rack. I should have clarified what I was looking for, which was an event-based micro web framework.

Event machine is what's underpinning cramp, which is what I went for, and it does the job ok. The problems I had were to do with less than full support from the top to the bottom of the stack (basically the only server I could use was Thin, and there was no way to get anything working with Torquebox that I could find)

> Your Rails application can only have as many clients total as you have workers if they all keep a permanent connection.

So even though it's event-based, if I have 1000 clients long-polling (or SSE'ing, or whatever) that would tie up all my workers? I may have misunderstood what we were getting in Rails 4, then.

> So even though it's event-based

Rails is not event-based. An evented systems can have an n:m relation between workers and clients.

> I may have misunderstood what we were getting in Rails 4, then.

Yeah, or I did. As far as i understood, Rails 4 just adds streaming responses: the client starts getting bytes as soon as you start generating them (by calling `response.write` or whatever). That's not evented, that's just writing to the response stream, you can do that in CGI if you want.

Rack 1.x doesn't have end-to-end streaming, and certainly not with a socket-style API. The Rack specification mandates buffering and rewinding input, and while it's possible to write a rewindable input stream (I've actually seen it done) nobody has ever written a stable one.

EventMachine is poorly maintained and doesn't have the same level of community support as Node.js, not to mention an ugly API. Of course, Node.js doesn't have the same level of maturity as Twisted Python but Twisted doesn't get any hype whatsoever.