Profile of lib/PONAPI/DAO/Request.pm

← Index
NYTProf Performance Profile «line view»
For script/ponapi
Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:11 2016

Filename | /home/mickey/git_tree/PONAPI/Server/lib/PONAPI/DAO/Request.pm
Statements | Executed 2400529 statements in 10.1s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
100001 | 2 | 1 | 6.57s | 18.1s | PONAPI::DAO::Request::::BUILDPONAPI::DAO::Request::BUILD
100001 | 2 | 2 | 3.43s | 86.9s | PONAPI::DAO::Request::::responsePONAPI::DAO::Request::response
100001 | 1 | 1 | 2.49s | 7.76s | PONAPI::DAO::Request::::BUILDARGSPONAPI::DAO::Request::BUILDARGS
100001 | 1 | 1 | 317ms | 317ms | PONAPI::DAO::Request::::_validate_rel_typePONAPI::DAO::Request::_validate_rel_type
100001 | 2 | 1 | 279ms | 279ms | PONAPI::DAO::Request::::__ANON__[lib/PONAPI/DAO/Request.pm:36]PONAPI::DAO::Request::__ANON__[lib/PONAPI/DAO/Request.pm:36]
50245 | 1 | 1 | 165ms | 165ms | PONAPI::DAO::Request::::_validate_idPONAPI::DAO::Request::_validate_id
1 | 1 | 1 | 1000µs | 537ms | PONAPI::DAO::Request::::BEGIN@7PONAPI::DAO::Request::BEGIN@7
1 | 1 | 1 | 16µs | 3.19ms | PONAPI::DAO::Request::::BEGIN@4PONAPI::DAO::Request::BEGIN@4
1 | 1 | 1 | 13µs | 55µs | PONAPI::DAO::Request::::BEGIN@5PONAPI::DAO::Request::BEGIN@5
1 | 1 | 1 | 9µs | 99µs | PONAPI::DAO::Request::::BEGIN@162PONAPI::DAO::Request::BEGIN@162
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::__ANON__[lib/PONAPI/DAO/Request.pm:30]PONAPI::DAO::Request::__ANON__[lib/PONAPI/DAO/Request.pm:30]
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::__ANON__[lib/PONAPI/DAO/Request.pm:43]PONAPI::DAO::Request::__ANON__[lib/PONAPI/DAO/Request.pm:43]
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_bad_requestPONAPI::DAO::Request::_bad_request
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_validate_fieldsPONAPI::DAO::Request::_validate_fields
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_validate_filterPONAPI::DAO::Request::_validate_filter
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_validate_includePONAPI::DAO::Request::_validate_include
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_validate_pagePONAPI::DAO::Request::_validate_page
0 | 0 | 0 | 0s | 0s | PONAPI::DAO::Request::::_validate_sortPONAPI::DAO::Request::_validate_sort

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | # ABSTRACT: DAO request class
2 |  |  |  |  | package PONAPI::DAO::Request;
3 |  |  |  |  |
4 | 2 | 46µs | 2 | 6.36ms | # spent 3.19ms (16µs+3.17) within PONAPI::DAO::Request::BEGIN@4 which was called: # once (16µs+3.17ms) by Module::Runtime::require_module at line 4 use Moose; # spent 3.19ms making 1 call to PONAPI::DAO::Request::BEGIN@4 # spent 3.17ms making 1 call to Moose::import
5 | 2 | 27µs | 2 | 96µs | # spent 55µs (13+42) within PONAPI::DAO::Request::BEGIN@5 which was called: # once (13µs+42µs) by Module::Runtime::require_module at line 5 use JSON::XS; # spent 55µs making 1 call to PONAPI::DAO::Request::BEGIN@5 # spent 42µs making 1 call to Exporter::import
6 |  |  |  |  |
7 | 2 | 663µs | 1 | 537ms | # spent 537ms (1000µs+536) within PONAPI::DAO::Request::BEGIN@7 which was called: # once (1000µs+536ms) by Module::Runtime::require_module at line 7 use PONAPI::Builder::Document; # spent 537ms making 1 call to PONAPI::DAO::Request::BEGIN@7
8 |  |  |  |  |
9 | 1 | 2µs | 1 | 2.08ms | has repository => ( # spent 2.08ms making 1 call to Moose::has
10 |  |  |  |  | is => 'ro',
11 |  |  |  |  | does => 'PONAPI::Repository',
12 |  |  |  |  | required => 1,
13 |  |  |  |  | );
14 |  |  |  |  |
15 | 1 | 2µs | 1 | 1.21ms | has document => ( # spent 1.21ms making 1 call to Moose::has
16 |  |  |  |  | is => 'ro',
17 |  |  |  |  | isa => 'PONAPI::Builder::Document',
18 |  |  |  |  | required => 1,
19 |  |  |  |  | );
20 |  |  |  |  |
21 | 1 | 1µs | 1 | 1.42ms | has type => ( # spent 1.42ms making 1 call to Moose::has
22 |  |  |  |  | is => 'ro',
23 |  |  |  |  | isa => 'Str',
24 |  |  |  |  | required => 1,
25 |  |  |  |  | );
26 |  |  |  |  |
27 |  |  |  |  | has send_doc_self_link => (
28 |  |  |  |  | is => 'ro',
29 |  |  |  |  | isa => 'Bool',
30 |  |  |  |  | default => sub { 0 },
31 | 1 | 5µs | 1 | 1.66ms | ); # spent 1.66ms making 1 call to Moose::has
32 |  |  |  |  |
33 |  |  |  |  | has is_valid => (
34 |  |  |  |  | is => 'ro',
35 |  |  |  |  | isa => 'Bool',
36 | 100001 | 671ms |  |  | # spent 279ms within PONAPI::DAO::Request::__ANON__[lib/PONAPI/DAO/Request.pm:36] which was called 100001 times, avg 3µs/call: # 50245 times (137ms+0s) by PONAPI::DAO::Request::RetrieveAll::new at line 79 of (eval 45)[Eval/Closure.pm:144], avg 3µs/call # 49756 times (142ms+0s) by PONAPI::DAO::Request::Retrieve::new at line 86 of (eval 45)[Eval/Closure.pm:144], avg 3µs/call default => sub { 1 },
37 | 1 | 6µs | 1 | 7.34ms | writer => '_set_is_valid', # spent 7.34ms making 1 call to Moose::has
38 |  |  |  |  | );
39 |  |  |  |  |
40 |  |  |  |  | has json => (
41 |  |  |  |  | is => 'ro',
42 |  |  |  |  | isa => 'JSON::XS',
43 |  |  |  |  | default => sub { JSON::XS->new->allow_nonref->utf8->canonical },
44 | 1 | 5µs | 1 | 2.05ms | ); # spent 2.05ms making 1 call to Moose::has
45 |  |  |  |  |
46 |  |  |  |  | # spent 7.76s (2.49+5.27) within PONAPI::DAO::Request::BUILDARGS which was called 100001 times, avg 78µs/call: # 100001 times (2.49s+5.27s) by PONAPI::DAO::Request::Retrieve::new or PONAPI::DAO::Request::RetrieveAll::new at line 15 of (eval 45)[Eval/Closure.pm:144], avg 78µs/call sub BUILDARGS {
47 | 100001 | 71.6ms |  |  | my $class = shift;
48 | 100001 | 780ms |  |  | my %args = @_ == 1 ? %{ $_[0] } : @_;
49 |  |  |  |  |
50 | 100001 | 110ms |  |  | die "[__PACKAGE__] missing arg `version`"
51 |  |  |  |  | unless defined $args{version};
52 |  |  |  |  |
53 | 100001 | 976ms | 100001 | 5.27s | $args{document} = PONAPI::Builder::Document->new( # spent 5.27s making 100001 calls to PONAPI::Builder::Document::new, avg 53µs/call
54 |  |  |  |  | version => $args{version},
55 |  |  |  |  | req_path => $args{req_path} // '/',
56 |  |  |  |  | req_base => $args{req_base} // '/',
57 |  |  |  |  | );
58 |  |  |  |  |
59 | 100001 | 472ms |  |  | return \%args;
60 |  |  |  |  | }
61 |  |  |  |  |
62 |  |  |  |  | # These validation methods will be overwritten in the appropriate roles.
63 |  |  |  |  | # They cover the case where an attribute is NOT expected.
64 |  |  |  |  | # spent 165ms within PONAPI::DAO::Request::_validate_id which was called 50245 times, avg 3µs/call: # 50245 times (165ms+0s) by PONAPI::DAO::Request::BUILD at line 114, avg 3µs/call sub _validate_id {
65 | 50245 | 25.7ms |  |  | my ( $self, $args ) = @_;
66 | 50245 | 277ms |  |  | return unless defined $args->{id};
67 |  |  |  |  | $self->_bad_request( "`id` is not allowed for this request" )
68 |  |  |  |  | }
69 |  |  |  |  |
70 |  |  |  |  | # spent 317ms within PONAPI::DAO::Request::_validate_rel_type which was called 100001 times, avg 3µs/call: # 100001 times (317ms+0s) by PONAPI::DAO::Request::BUILD at line 115, avg 3µs/call sub _validate_rel_type {
71 | 100001 | 58.5ms |  |  | my ( $self, $args ) = @_;
72 | 100001 | 519ms |  |  | return unless defined $args->{rel_type};
73 |  |  |  |  | $self->_bad_request( "`relationship type` is not allowed for this request" );
74 |  |  |  |  | }
75 |  |  |  |  |
76 |  |  |  |  | sub _validate_include {
77 |  |  |  |  | my ( $self, $args ) = @_;
78 |  |  |  |  | return unless defined $args->{include};
79 |  |  |  |  | $self->_bad_request( "`include` is not allowed for this request" );
80 |  |  |  |  | }
81 |  |  |  |  |
82 |  |  |  |  | sub _validate_fields {
83 |  |  |  |  | my ( $self, $args ) = @_;
84 |  |  |  |  | return unless defined $args->{fields};
85 |  |  |  |  | $self->_bad_request( "`fields` is not allowed for this request" );
86 |  |  |  |  | }
87 |  |  |  |  |
88 |  |  |  |  | sub _validate_filter {
89 |  |  |  |  | my ( $self, $args ) = @_;
90 |  |  |  |  | return unless defined $args->{filter};
91 |  |  |  |  | $self->_bad_request( "`filter` is not allowed for this request" );
92 |  |  |  |  | }
93 |  |  |  |  |
94 |  |  |  |  | sub _validate_sort {
95 |  |  |  |  | my ( $self, $args ) = @_;
96 |  |  |  |  | return unless defined $args->{sort};
97 |  |  |  |  | $self->_bad_request( "`sort` is not allowed for this request" );
98 |  |  |  |  | }
99 |  |  |  |  |
100 |  |  |  |  | sub _validate_page {
101 |  |  |  |  | my ( $self, $args ) = @_;
102 |  |  |  |  | return unless defined $args->{page};
103 |  |  |  |  | $self->_bad_request( "`page` is not allowed for this request" );
104 |  |  |  |  | }
105 |  |  |  |  |
106 |  |  |  |  | # spent 18.1s (6.57+11.5) within PONAPI::DAO::Request::BUILD which was called 100001 times, avg 181µs/call: # 50245 times (3.39s+5.76s) by PONAPI::DAO::Request::RetrieveAll::new at line 154 of (eval 45)[Eval/Closure.pm:144], avg 182µs/call # 49756 times (3.19s+5.74s) by PONAPI::DAO::Request::Retrieve::new at line 161 of (eval 45)[Eval/Closure.pm:144], avg 180µs/call sub BUILD {
107 | 100001 | 60.8ms |  |  | my ( $self, $args ) = @_;
108 |  |  |  |  |
109 |  |  |  |  | # `type` exists
110 | 100001 | 291ms | 100001 | 359ms | my $type = $self->type; # spent 359ms making 100001 calls to PONAPI::DAO::Request::type, avg 4µs/call
111 | 100001 | 598ms | 200002 | 1.82s | return $self->_bad_request( "Type `$type` doesn't exist.", 404 ) # spent 1.48s making 100001 calls to Test::PONAPI::Repository::MockDB::has_type, avg 15µs/call # spent 333ms making 100001 calls to PONAPI::DAO::Request::repository, avg 3µs/call
112 |  |  |  |  | unless $self->repository->has_type( $type );
113 |  |  |  |  |
114 | 100001 | 337ms | 100001 | 700ms | $self->_validate_id($args); # spent 534ms making 49756 calls to PONAPI::DAO::Request::Role::HasID::_validate_id, avg 11µs/call # spent 165ms making 50245 calls to PONAPI::DAO::Request::_validate_id, avg 3µs/call
115 | 100001 | 288ms | 100001 | 317ms | $self->_validate_rel_type($args); # spent 317ms making 100001 calls to PONAPI::DAO::Request::_validate_rel_type, avg 3µs/call
116 | 100001 | 337ms | 100001 | 3.10s | $self->_validate_include($args); # spent 3.10s making 100001 calls to PONAPI::DAO::Request::Role::HasInclude::_validate_include, avg 31µs/call
117 | 100001 | 305ms | 100001 | 3.89s | $self->_validate_fields($args); # spent 3.89s making 100001 calls to PONAPI::DAO::Request::Role::HasFields::_validate_fields, avg 39µs/call
118 | 100001 | 265ms | 100001 | 302ms | $self->_validate_filter($args); # spent 302ms making 100001 calls to PONAPI::DAO::Request::Role::HasFilter::_validate_filter, avg 3µs/call
119 | 100001 | 292ms | 100001 | 556ms | $self->_validate_sort($args); # spent 556ms making 100001 calls to PONAPI::DAO::Request::Role::HasSort::_validate_sort, avg 6µs/call
120 | 100001 | 263ms | 100001 | 303ms | $self->_validate_page($args); # spent 303ms making 100001 calls to PONAPI::DAO::Request::Role::HasPage::_validate_page, avg 3µs/call
121 |  |  |  |  |
122 |  |  |  |  | # validate `data`
123 | 100001 | 1.06s | 100001 | 170ms | if ( exists $args->{data} ) { # spent 170ms making 100001 calls to UNIVERSAL::can, avg 2µs/call
124 |  |  |  |  | if ( $self->can('data') ) {
125 |  |  |  |  | $self->_validate_data;
126 |  |  |  |  | }
127 |  |  |  |  | else {
128 |  |  |  |  | $self->_bad_request( "request body is not allowed" );
129 |  |  |  |  | }
130 |  |  |  |  | }
131 |  |  |  |  | elsif ( $self->can('has_data') ) {
132 |  |  |  |  | $self->_bad_request( "request body is missing `data`" );
133 |  |  |  |  | }
134 |  |  |  |  | }
135 |  |  |  |  |
136 |  |  |  |  | # spent 86.9s (3.43+83.5) within PONAPI::DAO::Request::response which was called 100001 times, avg 869µs/call: # 50245 times (1.80s+49.8s) by PONAPI::DAO::Request::RetrieveAll::execute at line 23 of lib/PONAPI/DAO/Request/RetrieveAll.pm, avg 1.03ms/call # 49756 times (1.63s+33.6s) by PONAPI::DAO::Request::Retrieve::execute at line 26 of lib/PONAPI/DAO/Request/Retrieve.pm, avg 708µs/call sub response {
137 | 100001 | 81.0ms |  |  | my ( $self, @headers ) = @_;
138 | 100001 | 167ms | 100001 | 191ms | my $doc = $self->document; # spent 191ms making 100001 calls to PONAPI::DAO::Request::document, avg 2µs/call
139 |  |  |  |  |
140 | 100001 | 747ms | 300003 | 21.8s | $doc->add_self_link # spent 18.3s making 100001 calls to PONAPI::Builder::Document::has_link, avg 183µs/call # spent 3.27s making 100001 calls to PONAPI::Builder::Document::add_self_link, avg 33µs/call # spent 291ms making 100001 calls to PONAPI::DAO::Request::send_doc_self_link, avg 3µs/call
141 |  |  |  |  | if $self->send_doc_self_link && !$doc->has_link('self');
142 |  |  |  |  |
143 |  |  |  |  | return (
144 | 100001 | 1.03s | 300003 | 61.4s | $doc->status, # spent 58.8s making 100001 calls to PONAPI::Builder::Document::build, avg 588µs/call # spent 2.60s making 200002 calls to PONAPI::Builder::Document::status, avg 13µs/call
145 |  |  |  |  | \@headers,
146 |  |  |  |  | (
147 |  |  |  |  | $doc->status != 204
148 |  |  |  |  | ? $doc->build
149 |  |  |  |  | : ()
150 |  |  |  |  | ),
151 |  |  |  |  | );
152 |  |  |  |  | }
153 |  |  |  |  |
154 |  |  |  |  | sub _bad_request {
155 |  |  |  |  | my ( $self, $detail, $status ) = @_;
156 |  |  |  |  | $self->document->raise_error( $status||400, { detail => $detail } );
157 |  |  |  |  | $self->_set_is_valid(0);
158 |  |  |  |  | return;
159 |  |  |  |  | }
160 |  |  |  |  |
161 | 1 | 5µs | 2 | 4.12ms | __PACKAGE__->meta->make_immutable; # spent 4.11ms making 1 call to Class::MOP::Class::make_immutable # spent 13µs making 1 call to PONAPI::DAO::Request::meta
162 | 3 | 70µs | 2 | 190µs | # spent 99µs (9+90) within PONAPI::DAO::Request::BEGIN@162 which was called: # once (9µs+90µs) by Module::Runtime::require_module at line 162 no Moose; 1; # spent 99µs making 1 call to PONAPI::DAO::Request::BEGIN@162 # spent 90µs making 1 call to Moose::unimport
163 |  |  |  |  |
164 |  |  |  |  | __END__