Skip to content

Commit

Permalink
added experimental start_timer and stop_timer helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Sep 16, 2011
1 parent 206f99f commit ca9fcaa
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 15 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,6 +1,7 @@
This file documents the revision history for Perl extension Mojolicious.

1.99 2011-09-15 00:00:00
1.99 2011-09-16 00:00:00
- Added EXPERIMENTAL start_timer and stop_timer helpers.
- Improved documentation.
- Fixed small redirect_to bug. (judofyr, sri)
- Fixed small attribute selector bug in Mojo::DOM::CSS.
Expand Down
2 changes: 2 additions & 0 deletions lib/Mojolicious/Plugin/Charset.pm
Expand Up @@ -50,6 +50,8 @@ and encoding on all layers of L<Mojolicious>.
=head1 OPTIONS
L<Mojolicious::Plugin::Charset> supports the following options.
=head2 C<charset>
# Mojolicious::Lite
Expand Down
4 changes: 4 additions & 0 deletions lib/Mojolicious/Plugin/Config.pm
Expand Up @@ -142,6 +142,8 @@ ones like C<myapp.$mode.conf>.
=head1 OPTIONS
L<Mojolicious::Plugin::Config> supports the following options.
=head2 C<default>
# Mojolicious::Lite
Expand Down Expand Up @@ -174,6 +176,8 @@ Configuration stash key.
=head1 HELPERS
L<Mojolicious::Plugin::Config> implements the following helpers.
=head2 C<config>
<%= config 'something' %>
Expand Down
2 changes: 2 additions & 0 deletions lib/Mojolicious/Plugin/DefaultHelpers.pm
Expand Up @@ -125,6 +125,8 @@ example for learning to build new plugins.
=head1 HELPERS
L<Mojolicious::Plugin::DefaultHelpers> implements the following helpers.
=head2 C<app>
<%= app->secret %>
Expand Down
2 changes: 2 additions & 0 deletions lib/Mojolicious/Plugin/EPRenderer.pm
Expand Up @@ -119,6 +119,8 @@ example for learning to build new plugins.
=head1 OPTIONS
L<Mojolicious::Plugin::EPRenderer> supports the following options.
=head2 C<name>
# Mojolicious::Lite
Expand Down
4 changes: 4 additions & 0 deletions lib/Mojolicious/Plugin/I18N.pm
Expand Up @@ -127,6 +127,8 @@ The default lexicon class will only be generated if it doesn't already exist.
=head1 OPTIONS
L<Mojolicious::Plugin::I18N> supports the following options.
=head2 C<default>
# Mojolicious::Lite
Expand All @@ -143,6 +145,8 @@ Lexicon namespace, defaults to the application class followed by C<::I18N>.
=head1 HELPERS
L<Mojolicious::Plugin::I18N> implements the following helpers.
=head2 C<l>
<%=l 'hello' %>
Expand Down
6 changes: 3 additions & 3 deletions lib/Mojolicious/Plugin/JSONConfig.pm
Expand Up @@ -92,8 +92,8 @@ ones like C<myapp.$mode.json>.
=head1 OPTIONS
L<Mojolicious::Plugin::JSONConfig> accepts the same options as
L<Mojolicious::Plugin::Config> and the following new ones.
L<Mojolicious::Plugin::JSONConfig> inherits all options from
L<Mojolicious::Plugin::Config> and supports the following new ones.
=head2 C<template>
Expand All @@ -104,7 +104,7 @@ Template options.
=head1 HELPERS
L<Mojolicious::Plugin::JSONConfig> defines the same helpers as
L<Mojolicious::Plugin::JSONConfig> inherits all helpers from
L<Mojolicious::Plugin::Config>.
=head1 METHODS
Expand Down
4 changes: 4 additions & 0 deletions lib/Mojolicious/Plugin/PODRenderer.pm
Expand Up @@ -190,6 +190,8 @@ rawr!
=head1 OPTIONS
L<Mojolicious::Plugin::PODRenderer> supports the following options.
=head2 C<name>
# Mojolicious::Lite
Expand All @@ -214,6 +216,8 @@ Handler name of preprocessor.
=head1 HELPERS
L<Mojolicious::Plugin::PODRenderer> implements the following helpers.
=head2 C<pod_to_html>
<%= pod_to_html '=head2 lalala' %>
Expand Down
2 changes: 2 additions & 0 deletions lib/Mojolicious/Plugin/PoweredBy.pm
Expand Up @@ -43,6 +43,8 @@ example for learning to build new plugins.
=head1 OPTIONS
L<Mojolicious::Plugin::PoweredBy> supports the following options.
=head2 C<powered_by>
plugin PoweredBy => (name => 'MyApp 1.0');
Expand Down
55 changes: 45 additions & 10 deletions lib/Mojolicious/Plugin/RequestTimer.pm
@@ -1,27 +1,47 @@
package Mojolicious::Plugin::RequestTimer;
use Mojo::Base 'Mojolicious::Plugin';

use Time::HiRes ();
use Time::HiRes qw/gettimeofday tv_interval/;

# "I don't trust that doctor.
# I bet I've lost more patients than he's even treated."
sub register {
my ($self, $app) = @_;

# Add "start_timer" helper
$app->helper(
start_timer => sub {
my ($self, $name) = @_;
$self->stash->{'mojo.timer'}->{$name} = [gettimeofday()];
}
);

# Add "stop_timer" helper
$app->helper(
stop_timer => sub {
my ($self, $name) = @_;
my $elapsed = sprintf '%f',
tv_interval($self->stash->{'mojo.timer'}->{$name}, [gettimeofday()]);
return
wantarray
? ($elapsed, $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed)
: $elapsed;
}
);

# Start timer
$app->hook(
after_static_dispatch => sub {
my $self = shift;

# Ignore static files
my $stash = $self->stash;
return if $stash->{'mojo.static'} || $stash->{'mojo.started'};
return if $self->stash->{'mojo.static'};
my $req = $self->req;
my $method = $req->method;
my $path = $req->url->path->to_abs_string;
my $ua = $req->headers->user_agent || 'Anonymojo';
$self->app->log->debug("$method $path ($ua).");
$stash->{'mojo.started'} = [Time::HiRes::gettimeofday()];
$self->start_timer('request');
}
);

Expand All @@ -31,15 +51,11 @@ sub register {
my $self = shift;

# Ignore static files
my $stash = $self->stash;
return unless my $started = delete $stash->{'mojo.started'};
return if $stash->{'mojo.static'};
my $elapsed = sprintf '%f',
Time::HiRes::tv_interval($started, [Time::HiRes::gettimeofday()]);
my $rps = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
return if $self->stash->{'mojo.static'};
my $res = $self->res;
my $code = $res->code || 200;
my $message = $res->message || $res->default_message($code);
my ($elapsed, $rps) = $self->stop_timer('request');
$self->app->log->debug("$code $message (${elapsed}s, $rps/s).");
}
);
Expand Down Expand Up @@ -67,6 +83,25 @@ timing information.
This is a core plugin, that means it is always enabled and its code a good
example for learning to build new plugins.
=head1 HELPERS
L<Mojolicious::Plugin::RequestTimer> implements the following helpers.
=head2 C<start_timer>
<% start_timer 'page'; %>
Start timer.
Note that this helper is EXPERIMENTAL and might change without warning!
=head2 C<stop_timer>
<%= stop_timer 'page' %>
<%= (stop_timer('page'))[1] %>
Stop timer and return elapsed time in seconds.
Note that this helper is EXPERIMENTAL and might change without warning!
=head1 METHODS
L<Mojolicious::Plugin::RequestTimer> inherits all methods from
Expand Down
2 changes: 2 additions & 0 deletions lib/Mojolicious/Plugin/TagHelpers.pm
Expand Up @@ -370,6 +370,8 @@ always be generated automatically.
=head1 HELPERS
L<Mojolicious::Plugin::TagHelpers> implements the following helpers.
=head2 C<base_tag>
<%= base_tag %>
Expand Down
24 changes: 23 additions & 1 deletion t/mojolicious/tag_helper_lite_app.t
Expand Up @@ -7,7 +7,7 @@ BEGIN {
$ENV{MOJO_IOWATCHER} = 'Mojo::IOWatcher';
}

use Test::More tests => 51;
use Test::More tests => 57;

# "Hey! Bite my glorious golden ass!"
use Mojolicious::Lite;
Expand Down Expand Up @@ -43,6 +43,16 @@ get 'form/:test' => 'form';
# PUT /selection
put 'selection';

# GET /timed
get '/timed' => sub {
my $self = shift;
$self->start_timer('page');
$self->render(inline => '<%= stop_timer "page" %> seconds');
};

# GET /rps
get '/rps';

my $t = Test::Mojo->new;

# GET /tags
Expand Down Expand Up @@ -296,6 +306,13 @@ $t->put_ok('/selection?foo=bar&a=e&foo=baz&bar=d')->status_is(200)
. '</form>'
. "\n");

# GET /timed
$t->get_ok('/timed')->status_is(200)->content_like(qr/\d+\.\d+\ seconds$/);

# GET /rps
$t->get_ok('/rps')->status_is(200)
->content_like(qr/^lalala\n\d+\.\d+s\ \(\d+\.\d+\/s\)/);

__DATA__
@@ tags.html.ep
<%= tag 'foo' %>
Expand Down Expand Up @@ -392,3 +409,8 @@ __DATA__
%= select_field bar => [['D' => 'd', disabled => 'disabled'], 'baz']
%= submit_button
%= end
@@ rps.html.ep
% start_timer 'foo';
lalala
<%= (stop_timer('foo'))[0] %>s (<%= (stop_timer('foo'))[1] %>/s)

0 comments on commit ca9fcaa

Please sign in to comment.