From 591c90a2ac4ea419a062bf19fffb0831d06786df Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 9 Oct 2015 15:29:05 +0100 Subject: Speed up admin front page. * Don't show a categories summary unless asked via a link * Don't needlessly join in questionnaire/update summaries * Switch count(distinct()) to a subselect as it turns out select count(*) from (select distinct(user_id) from problem) temp; is a lot quicker than select count(distinct(user_id)) from problem; --- perllib/FixMyStreet/App/Controller/Admin.pm | 4 ++- perllib/FixMyStreet/DB/ResultSet/Comment.pm | 19 +++++++------- perllib/FixMyStreet/DB/ResultSet/Problem.pm | 5 +++- perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm | 30 +++++++++++++---------- templates/web/base/admin/index.html | 12 +++++---- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 39d6ff72f..a61032988 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -129,7 +129,9 @@ sub index : Path : Args(0) { : _('n/a'); $c->stash->{questionnaires} = \%questionnaire_counts; - $c->stash->{categories} = $c->cobrand->problems->categories_summary(); + if ($c->get_param('show_categories')) { + $c->stash->{categories} = $c->cobrand->problems->categories_summary(); + } $c->stash->{total_bodies} = $c->model('DB::Body')->count(); diff --git a/perllib/FixMyStreet/DB/ResultSet/Comment.pm b/perllib/FixMyStreet/DB/ResultSet/Comment.pm index 270501efc..1b6afb819 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Comment.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Comment.pm @@ -32,15 +32,16 @@ sub timeline { sub summary_count { my ( $rs, $body_restriction ) = @_; - return $rs->to_body($body_restriction)->search( - undef, - { - group_by => ['me.state'], - select => [ 'me.state', { count => 'me.id' } ], - as => [qw/state state_count/], - join => 'problem' - } - ); + my $params = { + group_by => ['me.state'], + select => [ 'me.state', { count => 'me.id' } ], + as => [qw/state state_count/], + }; + if ($body_restriction) { + $rs = $rs->to_body($body_restriction); + $params->{join} = 'problem'; + } + return $rs->search(undef, $params); } 1; diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm index 40076d374..e9f5d0f8e 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm @@ -210,7 +210,10 @@ sub unique_users { return $rs->search( { state => [ FixMyStreet::DB::Result::Problem->visible_states() ], }, { - select => [ { count => { distinct => 'user_id' } } ], + select => [ { distinct => 'user_id' } ], + as => [ 'user_id' ] + } )->as_subselect_rs->search( undef, { + select => [ { count => 'user_id' } ], as => [ 'count' ] } )->first->get_column('count'); } diff --git a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm index db4b6e23e..bf1c68c49 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm @@ -113,6 +113,13 @@ sub send_questionnaires_period { sub timeline { my ( $rs, $restriction ) = @_; + my $attrs; + if (%$restriction) { + $attrs = { + -select => [qw/me.*/], + prefetch => [qw/problem/], + } + } return $rs->search( { -or => { @@ -121,24 +128,21 @@ sub timeline { }, %{ $restriction }, }, - { - -select => [qw/me.*/], - prefetch => [qw/problem/], - } + $attrs ); } sub summary_count { my ( $rs, $restriction ) = @_; - return $rs->search( - $restriction, - { - group_by => [ \'whenanswered is not null' ], - select => [ \'(whenanswered is not null)', { count => 'me.id' } ], - as => [qw/answered questionnaire_count/], - join => 'problem' - } - ); + my $params = { + group_by => [ \'whenanswered is not null' ], + select => [ \'(whenanswered is not null)', { count => 'me.id' } ], + as => [qw/answered questionnaire_count/], + }; + if (%$restriction) { + $params->{join} = 'problem'; + } + return $rs->search($restriction, $params); } 1; diff --git a/templates/web/base/admin/index.html b/templates/web/base/admin/index.html index 8c49a5685..dde6523a3 100644 --- a/templates/web/base/admin/index.html +++ b/templates/web/base/admin/index.html @@ -55,14 +55,16 @@ and to receive notices of updates.

[% loc('Update breakdown by state') %]

[% PROCESS states object=comments list=comments.keys.sort %] -[% FOREACH category IN categories %] - [% IF loop.first %] -

[% loc('Category fix rate for problems > 4 weeks old') %]

+[% IF categories.size %] +

[% loc('Category fix rate for problems > 4 weeks old') %]

- [% END %] +[% FOREACH category IN categories %] - [% '
[% loc('Category') %][% loc('Total') %][% loc('Fixed') %]
[% category.key %][% category.value.total %][% category.value.fixed / category.value.total * 100 | format('%.1f') %]%
' IF loop.last %] +[% END %] + +[% ELSE %] +

[% loc('Category fix rate for problems > 4 weeks old') %]

[% END %] [% INCLUDE 'admin/footer.html' %] -- cgit v1.2.3 From af7a602d2c83bdf0371ae253f5ba3f80cece077d Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 9 Oct 2015 16:15:38 +0100 Subject: Add status page. --- perllib/FixMyStreet/App/Controller/Status.pm | 70 ++++++++++++++++++++++++++++ templates/web/base/status/index.html | 19 ++++++++ 2 files changed, 89 insertions(+) create mode 100755 perllib/FixMyStreet/App/Controller/Status.pm create mode 100644 templates/web/base/status/index.html diff --git a/perllib/FixMyStreet/App/Controller/Status.pm b/perllib/FixMyStreet/App/Controller/Status.pm new file mode 100755 index 000000000..907fe5456 --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Status.pm @@ -0,0 +1,70 @@ +package FixMyStreet::App::Controller::Status; +use Moose; +use namespace::autoclean; + +use HTTP::Negotiate; +use JSON; + +BEGIN { extends 'Catalyst::Controller'; } + +=head1 NAME + +FixMyStreet::App::Controller::Status - Catalyst Controller + +=head1 DESCRIPTION + +Status page Catalyst Controller. + +=head1 METHODS + +=cut + +sub index_json : Path('/status.json') : Args(0) { + my ($self, $c) = @_; + $c->forward('index', [ 'json' ]); +} + +sub index : Path : Args(0) { + my ($self, $c, $format) = @_; + + # Fetch summary stats from admin front page + $c->forward('/admin/index'); + + # Fetch git version + $c->forward('/admin/config_page'); + + my $chosen = $format; + unless ($chosen) { + my $variants = [ + ['html', undef, 'text/html', undef, undef, undef, undef], + ['json', undef, 'application/json', undef, undef, undef, undef], + ]; + $chosen = HTTP::Negotiate::choose($variants, $c->req->headers); + $chosen = 'html' unless $chosen; + } + + # TODO Perform health checks here + + if ($chosen eq 'json') { + $c->res->content_type('application/json; charset=utf-8'); + my $data = { + version => $c->stash->{git_version}, + reports => $c->stash->{total_problems_live}, + updates => $c->stash->{comments}{confirmed}, + alerts_confirmed => $c->stash->{alerts}{1}, + alerts_unconfirmed => $c->stash->{alerts}{0}, + questionnaires_sent => $c->stash->{questionnaires}{total}, + questionnaires_answered => $c->stash->{questionnaires}{1}, + bodies => $c->stash->{total_bodies}, + contacts => $c->stash->{contacts}{total}, + }; + my $body = JSON->new->utf8(1)->pretty->encode($data); + $c->res->body($body); + } + + return 1; +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/templates/web/base/status/index.html b/templates/web/base/status/index.html new file mode 100644 index 000000000..9ed4292b7 --- /dev/null +++ b/templates/web/base/status/index.html @@ -0,0 +1,19 @@ +[% INCLUDE 'header.html' title=loc('Summary') bodyclass='fullwidthpage' %] + +

[% loc('Summary') %]

+ +
+
Version
+
[% git_version || 'unknown' %]
+
+ + + +[% INCLUDE 'footer.html' %] -- cgit v1.2.3