Forum: Rails-core (closed, excessive spam) Armageddon?

Posted by Kyle Maxwell (Guest)
on 2006-04-20 23:12
(Received via mailing list)
Is there anything that the community can do to jumpstart/accelerate
this project?

For those that missed Canada on Rails Armageddon is roughly Comet
(http://www.irishdev.com/NewsArticle.aspx?id=2166) on Rails.

--
Kyle Maxwell
Chief Technologist
E Factor Media // FN Interactive
kyle@efactormedia.com
1-866-263-3261
Posted by Jon Tirsen (Guest)
on 2006-04-21 03:20
(Received via mailing list)
Wow! This is really cool stuff.

But indeed not without problems. Problems that are solvable of course,
but it does change a lot of the current deployment model of Rails.

If I've understood Comet correctly the web browser opens an http
connection to the server and keeps it open. When something happens the
server can use the open connection to push stuff to the browser.

Please correct me if I'm wrong in my understanding of Comet and if I
indeed am wrong then you can safely skip the rest of this email as it
assumes that the above is correct.

Problem of course is that with the current deployment model of Rails
each open connection is going to allocate one FastCGI process and keep
it allocated until the connection is closed. So with the typical Rails
deployment of about twenty FastCGI processes you can have, let's
think.... about twenty concurrent users! Sorry for saying the s-word
here but.... this ehm... doesn't scale. :-)

The solution here is of course non-blocking I/O. You need to configure
Apache to reverse proxy to some process that can have as many open
connections it likes with just one single thread. Then you use
non-blocking I/O to read and write from the connection. Problem with
non-blocking I/O of course is that it completely changes the way you
write your programs. Unless of course.... you use Ruby! Because in
Ruby there's this wonderful little invention called continuations.
Rarely used but in some situations it's just a perfect fit! With
continuations you can make a non-blocking I/O program look exactly
like a blocking one completely hiding the plumbing. The interested
reader can work out the details themselves. :-)

Another option is that you only allow data browser-bound messages on
the Comet connection and those have a limited size only. You still set
up the reverse proxy configuration and configure the write-buffers of
the connections to be at least as big as the size of the biggest
message. When you want to send a message you make sure there's enough
space in the write buffer so that the write doesn't block. This is
trickier to get right and is going to be very OS dependent. I know
Linux and BSD does things differently here and I have no idea how
Windows does it (if it does at all).

Another simpler problem is that proxies and other infrastructure is
going to close HTTP connections if they've been open for too long. In
this case you simply have to have a client that's good at reopening
the connections. But the problem is: What if stuff has happened while
the connection was closed! So there needs to be away of queueing up
outgoing messages and timing them out if indeed the client doesn't
reconnect.

Indeed very interesting stuff.

Are we rewriting a complete messaging infrastructure software in Rails
here or is there a way of doing this that's so incredibly clever and
simple that I've completely missed it. Mind you, I'm definitely not
ruling this option out.

Cheers,
Jon
Posted by Giles Bowkett (Guest)
on 2006-04-21 03:29
(Received via mailing list)
> Are we rewriting a complete messaging infrastructure software in Rails
> here or is there a way of doing this that's so incredibly clever and
> simple that I've completely missed it.

There is a way of doing this that is so incredibly clever and simple
that you've completely missed it.

I got to see it at Canada on Rails and I think you'll see it soon
enough. I'd tell you but I don't want to ruin the surprise.

--
Giles Bowkett
http://www.gilesgoatboy.org
Posted by Eric Woodward (Guest)
on 2006-04-22 05:00
(Received via mailing list)
That's lame. Please ruin the "surprise".

--ejw

Eric Woodward
Email: ejw@statewood.com
Posted by Andrew Kaspick (akaspick)
on 2006-04-22 05:21
(Received via mailing list)
I see no point in holding back either.

I was at CoR as well and saw the same stuff.  I thought it was cool,
but it's not as groundbreaking as you might think.

Comet uses iframe hacks and armageddon uses a flash "hack".  Yes, I
said hack. :)  Although the solution looks much cleaner, I don't
believe it to be as portable a solution because of the use of flash,
but does that matter???  I don't know, we'll see I guess.

Looking forward to seeing more info on Armageddon though.
Posted by Jon Tirsen (Guest)
on 2006-04-22 09:14
(Received via mailing list)
But that's just on the browser side of things which is relatively easy
to do (although you can't use XHR of course). The hard thing is
scaling things on the server side because of the
one-fastcgi-process-per-request problem and the fact that a "Comet
request" never ends.
Posted by Richard Friend (Guest)
on 2006-04-22 13:27
(Received via mailing list)
One of the primary reasons for the success of the http protocol and the
Internet in general its stateless nature, this is being further extended
into things like REST web services.

In a model like this wouldn't you have to ensure that everything is 
thread
safe?

To me this looks like a step backwards, although maybe I am just not 
getting
it.
Posted by sanzbox@yahoo.com (Guest)
on 2006-04-22 14:29
(Received via mailing list)
Instant messenger like systems help illustrate the
problem:  Try http://www.meebo.com/ or the integrated
Talk/Chat feature of GMail for examples.  Long-running
requests solve a class of low-latency communication
techniques that would otherwise overwhelm the server
with polling traffic for similar performance.

The Meebo folks claimed they tried their hand at
fastcgi and gave up to create their own custom
lighttpd plugin.  I'd love to see what Armageddon has
in mind to solve this.

Cheers,

-San

--- Richard Friend <rik.friend@gmail.com> wrote:

> To me this looks like a step backwards, although
> > one-fastcgi-process-per-request problem and the
> think.
> > > Looking forward to seeing more info on
> > > > Email: ejw@statewood.com
> > > > >
> > > > > Giles Bowkett
> > > > > http://www.gilesgoatboy.org
> > > > >
> _______________________________________________
> > > > > Rails-core mailing list
> > > > > Rails-core@lists.rubyonrails.org
> > > > >
>
http://lists.rubyonrails.org/mailman/listinfo/rails-core
> > > > >
> > > > >
> > > > >
> > > >
> > > >
> _______________________________________________
> > > > Rails-core mailing list
> > > > Rails-core@lists.rubyonrails.org
> > > >
>
http://lists.rubyonrails.org/mailman/listinfo/rails-core
> > > >
> > > _______________________________________________
> > > Rails-core mailing list
> > > Rails-core@lists.rubyonrails.org
> > >
>
http://lists.rubyonrails.org/mailman/listinfo/rails-core
> > >
> > _______________________________________________
> > Rails-core mailing list
> > Rails-core@lists.rubyonrails.org
> >
>
http://lists.rubyonrails.org/mailman/listinfo/rails-cor
> >
> > _______________________________________________
> Rails-core mailing list
> Rails-core@lists.rubyonrails.org
>
http://lists.rubyonrails.org/mailman/listinfo/rails-core
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Posted by Obie Fernandez (Guest)
on 2006-04-22 17:16
(Received via mailing list)
I could have sworn DHH said he ran a Twisted server daemon
specifically to handle the long-lived Armageddon threads.

Obie

..who was raised as a JW hence found the Armageddon reference
particularly funny!
Posted by David Heinemeier Hansson (Guest)
on 2006-04-22 17:50
(Received via mailing list)
> I could have sworn DHH said he ran a Twisted server daemon
> specifically to handle the long-lived Armageddon threads.

Armageddon uses a separate socket server, so you don't have any
problems with each connection taking up a FCGI process. That would not
be very scalable. Which is the core objection I have against Comet: It
requires you to complete rearchitect your application.

Armageddon works with what already is.


Client A --opens socket to--> Socket Server
Client B --makes xhr call that client A should see--> FCGI --sends
message to--> Socket Server

So the socket server works like a bus. The great thing about this is
that the socket server is stupid simple. It's just a registry, which
allows you to send text to a socket identified by an id.

And since we already have this wonderful system known as RJS, we can
push RJS updates from client B to client A reusing the same templates
as client B used to update himself.

Very dry, very low-overhead, very easy to use and understand.
--
David Heinemeier Hansson
http://www.loudthinking.com -- Broadcasting Brain
http://www.basecamphq.com   -- Online project management
http://www.backpackit.com   -- Personal information manager
http://www.rubyonrails.com  -- Web-application framework
Posted by Jeff Lindsay (progrium)
on 2006-04-22 22:32
(Received via mailing list)
Client A opens a socket to the Socket Server? Real sockets? Or a
persistent HTTP connection?

-jeff

On 4/22/06, David Heinemeier Hansson <david.heinemeier@gmail.com> wrote:
>
> as client B used to update himself.
> Rails-core@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails-core
>


--
Jeff Lindsay
http://blogrium.com/
Posted by Jon Tirsen (Guest)
on 2006-04-23 00:26
(Received via mailing list)
Nice. Now I get it.

I agree. Comet isn't going to get very far if it requires you to
completely change your design. Event driven is an interesting design
concept but there's just too many existing apps and too much existing
know-how out there for building web apps the way we do now. (Which is
indeed slightly event driven but not to the extent Comet wants it to
be.)

Couple of questions:

The separate server uses threads or non-blocking I/O? I guess with
Ruby's current threading model you could scale to a couple of thousand
connections but threading is only going to take you about that far.
(Having native threads is going to limit it much earlier.)

What about temporary disconnects from the client? (HTTP infrastructure
usually doesn't like long-lived connections.) Is there a queuing
system in place so the client will receive those messages when he
reconnects? Doesn't have to be rocket science but I do think this is a
problem that needs to be solved.

You guys using this in Campfire? Planning to?

Cheers,
Jon
Posted by David Heinemeier Hansson (Guest)
on 2006-04-23 05:07
(Received via mailing list)
> Client A opens a socket to the Socket Server? Real sockets? Or a
> persistent HTTP connection?

Real sockets. That's why its using Flash.
--
David Heinemeier Hansson
http://www.loudthinking.com -- Broadcasting Brain
http://www.basecamphq.com   -- Online project management
http://www.backpackit.com   -- Personal information manager
http://www.rubyonrails.com  -- Web-application framework
Posted by David Heinemeier Hansson (Guest)
on 2006-04-23 05:14
(Received via mailing list)
> The separate server uses threads or non-blocking I/O? I guess with
> Ruby's current threading model you could scale to a couple of thousand
> connections but threading is only going to take you about that far.
> (Having native threads is going to limit it much earlier.)

Currently just using threads. But this is stupid simple stuff. The
socket server is tiny. It's an obvious fit to rewrite it in C to get
blazing speed. All the socket server does is match IDs to sockets and
pass messages through.

> What about temporary disconnects from the client? (HTTP infrastructure
> usually doesn't like long-lived connections.) Is there a queuing
> system in place so the client will receive those messages when he
> reconnects? Doesn't have to be rocket science but I do think this is a
> problem that needs to be solved.

We haven't yet digged into the failure modes. But it shouldn't be that
hard to do. Currently it just throws away the message if the socket
isn't there. So there are no retry semantics.

> You guys using this in Campfire? Planning to?

No and no. Going sockets add complexity. Which is fine when you need
it, but Campfire doesn't. You can make polling really, really cheap.
And we did. But I could definitely see us using it for other
applications. Say 3 people working in real-time on a single todo list.
--
David Heinemeier Hansson
http://www.loudthinking.com -- Broadcasting Brain
http://www.basecamphq.com   -- Online project management
http://www.backpackit.com   -- Personal information manager
http://www.rubyonrails.com  -- Web-application framework
Posted by Peter Michaux (Guest)
on 2006-04-23 05:38
(Received via mailing list)
On 4/22/06, David Heinemeier Hansson <david.heinemeier@gmail.com> wrote:


> No and no. Going sockets add complexity. Which is fine when you need
> it, but Campfire doesn't. You can make polling really, really cheap.
> And we did.

What did you do to make is so cheap? In Campfire how is this different
than three people working on one todo list?

Thanks,
Peter
Posted by David Heinemeier Hansson (Guest)
on 2006-04-23 06:14
(Received via mailing list)
> What did you do to make is so cheap? In Campfire how is this different
> than three people working on one todo list?

We rewrote the 100 lines of Ruby that handled the poll action in 300
lines of C. Jamis Buck did that in a couple of hours. Now each poll
just does two super cheap db calls and polling is no longer a
bottleneck.

Campfire and a shared todo list is different because they're not
working on a shared resource. There's no concept of locking. Or two
people dragging the same item. So a 3 second delay between posting and
showing up doesn't matter. It does when you're working on a shared
resource.
--
David Heinemeier Hansson
http://www.loudthinking.com -- Broadcasting Brain
http://www.basecamphq.com   -- Online project management
http://www.backpackit.com   -- Personal information manager
http://www.rubyonrails.com  -- Web-application framework
This topic is locked and can not be replied to.