Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: ModPerl: ModPerl

AJAX pseudo-push

 

 

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded


nicolas.george at normalesup

Nov 12, 2009, 10:53 AM

Post #1 of 13 (1204 views)
Permalink
AJAX pseudo-push

Hi.

There is an increasingly popular technique to emulate server-initiated push
over HTTP. I'm sure everyone here knows it well, but for the sake of
completeness: the clients sends a XMLHttpRequest to the server in the
background; the server does not answer it immediately, but keeps it for
later when there is actually something to say to the client; if the request
timeouts, the client re-sends it.

I am wondering if this technique is usable with Apache in general and
mod_perl in particular.

The obvious solution is to have the request handler sleep until it has
something to answer does not work, since it requires a worker thread and a
perl interpreter for each waiting client, and perl interpreters are few and
expensive.

The ideal solution would be if some part of the request handler could put
the current request (A) "on hold". Later, the handler for another request
(B) could retrieve the request A and generate an answer for it, or at least
wake it up.

Is something like this possible with Apache and mod_perl?

Regards,

--
Nicolas George
Attachments: signature.asc (0.19 KB)


perl at joelrichard

Nov 12, 2009, 11:49 AM

Post #2 of 13 (1165 views)
Permalink
Re: AJAX pseudo-push [In reply to]

I may be off base, but I think this technique would be ineffective
since the server process would be kept busy with an open connection to
the browser. Eventually you'll run out of processes what with all the
clients that end up waiting for something to happen. HTTP is a pull
protocol. :)

The best that I can think of is some sort of queue system (like a
message queue?) would be more appropriate to allow the browser to poll
the server periodically to see if the info is available. Once the info
becomes available, then the server can send it to the browser.
Thousands of light requests are better than hundreds of heavy ones.

But it seems to me that you're leaning towards some daemon that runs
in the background on the server, generating long-running responses to
requests that come from the server. This is close to what you
described with request A and B, but I'd have the actual request
handled by another daemon.

I can get into further detail and speculation, but maybe we'll leave
that as homework.

--Joel


On Nov 12, 2009, at 1:53 PM, Nicolas George wrote:

> Hi.
>
> There is an increasingly popular technique to emulate server-
> initiated push
> over HTTP. I'm sure everyone here knows it well, but for the sake of
> completeness: the clients sends a XMLHttpRequest to the server in the
> background; the server does not answer it immediately, but keeps it
> for
> later when there is actually something to say to the client; if the
> request
> timeouts, the client re-sends it.
>
> I am wondering if this technique is usable with Apache in general and
> mod_perl in particular.
>
> The obvious solution is to have the request handler sleep until it has
> something to answer does not work, since it requires a worker thread
> and a
> perl interpreter for each waiting client, and perl interpreters are
> few and
> expensive.
>
> The ideal solution would be if some part of the request handler
> could put
> the current request (A) "on hold". Later, the handler for another
> request
> (B) could retrieve the request A and generate an answer for it, or
> at least
> wake it up.
>
> Is something like this possible with Apache and mod_perl?
>
> Regards,
>
> --
> Nicolas George


pharkins at gmail

Nov 12, 2009, 12:22 PM

Post #3 of 13 (1159 views)
Permalink
Re: AJAX pseudo-push [In reply to]

On Thu, Nov 12, 2009 at 1:53 PM, Nicolas George
<nicolas.george [at] normalesup> wrote:
> There is an increasingly popular technique to emulate server-initiated push
> over HTTP. I'm sure everyone here knows it well, but for the sake of
> completeness: the clients sends a XMLHttpRequest to the server in the
> background; the server does not answer it immediately, but keeps it for
> later when there is actually something to say to the client; if the request
> timeouts, the client re-sends it.

I think you'd be better off using polling. There are tools for this
in the popular JS frameworks.

- Perrin


nicolas.george at normalesup

Nov 12, 2009, 12:33 PM

Post #4 of 13 (1171 views)
Permalink
Re: AJAX pseudo-push [In reply to]

Hi.

Le duodi 22 brumaire, an CCXVIII, Joel Richard a écrit :
> I may be off base, but I think this technique would be ineffective since
> the server process would be kept busy with an open connection to the
> browser. Eventually you'll run out of processes what with all the
> clients that end up waiting for something to happen. HTTP is a pull
> protocol. :)

This is not a protocol problem. May I remind that all Internet is based on
an unreliable packet protocol? The fact that HTTP is not connection-oriented
means that the server have to implement cookies and timeouts itself to track
clients instead of relying on the OS TCP stack, but that is not very hard.
VoIP systems that use UDP do the same.

The problem of the number of concurrent idle connections is not related to
the protocol but to the architecture of the server. Fundamentally, an idle
connection is just a socket and a few hundred bytes of data structures to
keep track of who the client is and what it wants. IRC and Jabber servers
handle hundreds of such connections every day without any problem, and it
makes barely any difference whether the reply to the client starts with
"<message to='foo'>" or with "HTTP/1.0 200 OK".

On the other hand, if the HTTP server is designed to keep a whole thread or
process busy for each active request, this will not work. But that is not
the only way to design an HTTP server.

That is why the core of my question here is not "is it possible?", because I
know it is possible (I have already implemented a proof of concept as a
stand-alone HTTP server), but: is it possible _with Apache and mod_perl_.

> The best that I can think of is some sort of queue system (like a
> message queue?) would be more appropriate to allow the browser to poll
> the server periodically to see if the info is available. Once the info
> becomes available, then the server can send it to the browser. Thousands
> of light requests are better than hundreds of heavy ones.

We are not talking of thousands of light requests vs. hundreds of heavy
ones, but of dozen of requests vs. exactly one request, all as light.

I will definitely not use polling, because polling means dozen of useless
requests and, when there is actually something, it has to wait to the next
round of polling.

Imagine a server with an AJAX-based chat room with about twenty people in
it. To get reasonable interactivity, there must not be more than about 2
seconds between poll rounds, which means at the very least ten requests per
second. Using pseudo-PUSH, with the same bandwidth you can serve hundreds of
clients with better interactivity.

If I can not do it with Apache and mod_perl, I will write my own HTTP
server. But that is a shame, because it has to serve static content too, and
that, Apache does definitely better than me.

Regards,

--
Nicolas George
Attachments: signature.asc (0.19 KB)


mpeters at plusthree

Nov 12, 2009, 12:46 PM

Post #5 of 13 (1161 views)
Permalink
Re: AJAX pseudo-push [In reply to]

On 11/12/2009 03:33 PM, Nicolas George wrote:

> If I can not do it with Apache and mod_perl, I will write my own HTTP
> server. But that is a shame, because it has to serve static content too, and
> that, Apache does definitely better than me.

I wouldn't write your own. There are other event based, asynchronous web
servers out there in Perl (HTTP::Server::Multiplex, Net::Server::Coro,
Tatsumaki) so better to pick one of those than write your own.

This technique in general falls under the umbrella term of "Comet", so
I'd search CPAN for that. When I did it I quickly saw Stardust.

--
Michael Peters
Plus Three, LP


JeanDamienDurand at free

Nov 12, 2009, 12:53 PM

Post #6 of 13 (1163 views)
Permalink
Re: AJAX pseudo-push [In reply to]

Le jeudi 12 novembre 2009 21:33:48, Nicolas George a écrit :
> he fact that HTTP is not connection-oriented
> means that the server have to implement cookies and timeouts itself to
> track clients instead of relying on the OS TCP stack, but that is not very
> hard.

Just to clarify your meaning, sole HTTP remains a stateless protocol -
independantly to the fact that tcp connection can be permanent (default but
not guaranteed behaviour since HTTP/1.1- unless stated otherwise in the
headers).

Cheers, JD.


pharkins at gmail

Nov 12, 2009, 1:20 PM

Post #7 of 13 (1157 views)
Permalink
Re: AJAX pseudo-push [In reply to]

On Thu, Nov 12, 2009 at 3:33 PM, Nicolas George
<nicolas.george [at] normalesup> wrote:
> I will definitely not use polling, because polling means dozen of useless
> requests and, when there is actually something, it has to wait to the next
> round of polling.

That's good enough for most applications, and the "nothing to see
here" requests can be handled very quickly.

If you really need to use Comet, the common approach is a non-blocking
server architecture. If you want to use mod_perl for it, you can read
about the approach Stas used here:
lxxi.org/files/spamcon07/Bekman-SMTP_Multiplexing.pdf

They wrote their own server that passes off to apache when something
happens, but these days you could use perlbal as your base. You can
look at things like lighttpd + FastCGI too, but you'd probably have to
write some C code there to avoid keeping a perl process busy.

- Perrin


nicolas.george at normalesup

Nov 12, 2009, 2:00 PM

Post #8 of 13 (1166 views)
Permalink
Re: AJAX pseudo-push [In reply to]

[. I think ezmlm has eaten my mail. Sorry if it arrives twice. ]

Le duodi 22 brumaire, an CCXVIII, Michael Peters a écrit :
> I wouldn't write your own. There are other event based, asynchronous web
> servers out there in Perl (HTTP::Server::Multiplex, Net::Server::Coro,
> Tatsumaki) so better to pick one of those than write your own.
>
> This technique in general falls under the umbrella term of "Comet", so
> I'd search CPAN for that. When I did it I quickly saw Stardust.

Thanks, I did not know the term "Comet". This will greatly help me to find
implementations that suit my needs.

And thanks also to Jeff Nokes for his useful pointer.

Unfortunately, it all seems to confirm that it can not be done with Apache.

Regards,

--
Nicolas George
Attachments: signature.asc (0.19 KB)


nicolas.george at normalesup

Nov 12, 2009, 2:06 PM

Post #9 of 13 (1161 views)
Permalink
Re: AJAX pseudo-push [In reply to]

Le duodi 22 brumaire, an CCXVIII, Perrin Harkins a écrit :
> That's good enough for most applications, and the "nothing to see
> here" requests can be handled very quickly.

For what I have in mind, the actual content is rather small so the overhead
of the empty requests is huge.

> If you really need to use Comet, the common approach is a non-blocking
> server architecture.

That is what I used for my proof-of-concept server.

> If you want to use mod_perl for it, you can read
> about the approach Stas used here:
> lxxi.org/files/spamcon07/Bekman-SMTP_Multiplexing.pdf

That seems like a rather strange design, but I will look into it. Thanks for
the pointer.

Regards,

--
Nicolas George
Attachments: signature.asc (0.19 KB)


sgifford at suspectclass

Nov 12, 2009, 11:19 PM

Post #10 of 13 (1161 views)
Permalink
Re: AJAX pseudo-push [In reply to]

Nicolas George <nicolas.george [at] normalesup> writes:

> Hi.
>
> There is an increasingly popular technique to emulate server-initiated push
> over HTTP. I'm sure everyone here knows it well, but for the sake of
> completeness: the clients sends a XMLHttpRequest to the server in the
> background; the server does not answer it immediately, but keeps it for
> later when there is actually something to say to the client; if the request
> timeouts, the client re-sends it.
>
> I am wondering if this technique is usable with Apache in general and
> mod_perl in particular.
>
> The obvious solution is to have the request handler sleep until it has
> something to answer does not work, since it requires a worker thread and a
> perl interpreter for each waiting client, and perl interpreters are few and
> expensive.

You could use Apache in the front to handle static content and proxy
to another server for mod_perl and/or a custom notification server you
write. Apache works very well in this type of setup.

If you haven't yet, you could also try this out and see if you hit
real performance problems. mod_perl interpreters can be heavyweight,
but there is a lot of shared data between them, so if most of your
interpreters are not doing much performance may be fine. Or maybe
not of course.

> The ideal solution would be if some part of the request handler could put
> the current request (A) "on hold". Later, the handler for another request
> (B) could retrieve the request A and generate an answer for it, or at least
> wake it up.

This is a very interesting idea, it might be possible to implement it
with a custom Apache module, or maybe even with mod_perl if you found
the right hooks.

----Scott.


davidnicol at gmail

Nov 13, 2009, 6:42 AM

Post #11 of 13 (1152 views)
Permalink
Re: AJAX pseudo-push [In reply to]

On Fri, Nov 13, 2009 at 1:19 AM, Scott Gifford <sgifford [at] suspectclass>
>
> This is a very interesting idea, it might be possible to implement it
> with a custom Apache module, or maybe even with mod_perl if you found
> the right hooks.
>
> ----Scott.


so we're talking about a mod_perl app that opens a file system socket
in its initialization phase and listens on it with <select> and when
there is something there, presents that something, possibly by
redirecting to a different page that does the presentation, otherwise
after timing out presents another meta-redirect back to the same page.

We might want these sockets to pool, but that would be an optimization
that can be deferred until it works right.

Do AJAX clients handle redirects correctly? if not that's okay, just
send a NOTHINGYET token and let the client explicitly retry.



--
"In the case of an infinite collection, the question of the existence
of a choice function is problematic"


listom at bestsolution

Nov 17, 2009, 8:49 AM

Post #12 of 13 (1122 views)
Permalink
Re: AJAX pseudo-push [In reply to]

Nicolas George schrieb:
> Hi.
>
> There is an increasingly popular technique to emulate server-initiated push
> over HTTP. I'm sure everyone here knows it well, but for the sake of
> completeness: the clients sends a XMLHttpRequest to the server in the
> background; the server does not answer it immediately, but keeps it for
> later when there is actually something to say to the client; if the request
> timeouts, the client re-sends it.
>
> I am wondering if this technique is usable with Apache in general and
> mod_perl in particular.
>
> The obvious solution is to have the request handler sleep until it has
> something to answer does not work, since it requires a worker thread and a
> perl interpreter for each waiting client, and perl interpreters are few and
> expensive.
>
> The ideal solution would be if some part of the request handler could put
> the current request (A) "on hold". Later, the handler for another request
> (B) could retrieve the request A and generate an answer for it, or at least
> wake it up.
>

What you describe here is called Continuations in Java world :-)

Tom

http://docs.codehaus.org/display/JETTY/Continuations


andy at hexten

Nov 17, 2009, 8:58 AM

Post #13 of 13 (1124 views)
Permalink
Re: AJAX pseudo-push [In reply to]

On 17 Nov 2009, at 16:49, Tom Schindl wrote:
> What you describe here is called Continuations in Java world :-)

Continuations in the Java world are the same as continuations everywhere - but not quite what the OP described :)

http://en.wikipedia.org/wiki/Comet_(programming)

--
Andy Armstrong, Hexten

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.