Skip to content

Commit

Permalink
improved real-time web recipes some more
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jan 11, 2012
1 parent 8828b9a commit 4e7c973
Showing 1 changed file with 45 additions and 38 deletions.
83 changes: 45 additions & 38 deletions lib/Mojolicious/Guides/Cookbook.pod
Expand Up @@ -230,15 +230,46 @@ into alien environments like foreign event loops.
The real-time web is a collection of technologies that include Comet
(long-polling), EventSource and WebSockets, which allow content to be pushed
to consumers as soon as it is generated, instead of relying on the more
traditional pull model.
traditional pull model. All built-in web servers use non-blocking I/O and are
based on the L<Mojo::IOLoop> reactor, which provides many very powerful
features that allow real-time web applications to scale extremely well.

=head2 Backend web services

Since L<Mojo::UserAgent> is also based on the L<Mojo::IOLoop> reactor, it
won't block the built-in web servers when used non-blocking, even for high
latency backend web services.

use Mojolicious::Lite;

# Search Twitter for "perl"
get '/' => sub {
my $self = shift;
$self->ua->get('http://search.twitter.com/search.json?q=perl' => sub {
my ($ua, $tx) = @_;
$self->render('twitter', results => $tx->res->json->{results});
});
};

app->start;
__DATA__

@@ twitter.html.ep
<!DOCTYPE html>
<html>
<head><title>Twitter results for "perl"</title></head>
<body>
% for my $result (@$results) {
<p><%= $result->{text} %></p>
% }
</body>
</html>

=head2 Timers

All built-in web servers use non-blocking I/O and are based on the
L<Mojo::IOLoop> reactor, which provides many very powerful features that
allow real-time web applications to scale extremely well. Timers for example
can be used to delay rendering of a response without blocking any other
requests that might be processed in parallel, like C<sleep> would.
Another primary feature of the L<Mojo::IOLoop> reactor are timers, which can
for example be used to delay rendering of a response, and unlike C<sleep>,
won't block any other requests that might be processed in parallel.

use Mojolicious::Lite;

Expand All @@ -252,56 +283,32 @@ requests that might be processed in parallel, like C<sleep> would.

app->start;

Recurring timers are slightly more powerful, but need to be dropped manually
again, or they would just keep running as long as the server process stays
Recurring timers are slightly more powerful, but need to be dropped manually,
or they would just keep getting emitted as long as the server process stays
up.

use Mojolicious::Lite;

# Count to 5 in 1 second steps
get '/' => sub {
my $self = shift;

# Start recurring timer
my $i = 1;
my $id = Mojo::IOLoop->recurring(1 => sub {
$self->write_chunk($i);
$self->finish if $i == 5;
$i++;
});
$self->on(finish => sub { Mojo::IOLoop->drop($id) });
};

app->start;

=head2 Backend web services

Since L<Mojo::UserAgent> is also based on the L<Mojo::IOLoop> reactor, it
won't block the built-in web servers when used non-blocking, even for high
latency backend web services.

use Mojolicious::Lite;

# Search Twitter for "perl"
get '/' => sub {
my $self = shift;
$self->ua->get('http://search.twitter.com/search.json?q=perl' => sub {
my ($ua, $tx) = @_;
$self->render('twitter', results => $tx->res->json->{results});
});
# Drop recurring timer
$self->on(finish => sub { Mojo::IOLoop->drop($id) });
};

app->start;
__DATA__

@@ twitter.html.ep
<!DOCTYPE html>
<html>
<head><title>Twitter results for "perl"</title></head>
<body>
% for my $result (@$results) {
<p><%= $result->{text} %></p>
% }
</body>
</html>
And remember that all events are processed cooperatively, so your callbacks
shouldn't block for too long.

=head2 WebSocket web service

Expand Down

0 comments on commit 4e7c973

Please sign in to comment.