X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine.pm;h=b42f8bfcc76ac3d8799950cf0aa2e726523522da;hb=02a53b81a62d7559d61f5dffbc57be0713c05129;hp=4141198f6b9244f93e863998dd66849d2e853323;hpb=89acad38288ee023e8f6398bbee9c1d2fd6fdbfe;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine.pm b/lib/Catalyst/Engine.pm index 4141198..b42f8bf 100644 --- a/lib/Catalyst/Engine.pm +++ b/lib/Catalyst/Engine.pm @@ -20,7 +20,7 @@ require Module::Pluggable::Fast; $Data::Dumper::Terse = 1; __PACKAGE__->mk_classdata('components'); -__PACKAGE__->mk_accessors(qw/request response state/); +__PACKAGE__->mk_accessors(qw/counter request response state/); *comp = \&component; *req = \&request; @@ -30,8 +30,9 @@ __PACKAGE__->mk_accessors(qw/request response state/); *finalize_output = \&finalize_body; # For statistics -our $COUNT = 1; -our $START = time; +our $COUNT = 1; +our $START = time; +our $RECURSION = 1000; =head1 NAME @@ -82,7 +83,7 @@ Regex search for a component. sub component { my $c = shift; - if ( @_ ) { + if (@_) { my $name = shift; @@ -100,6 +101,11 @@ sub component { return sort keys %{ $c->components }; } +=item $c->counter + +Returns a hashref containing coderefs and execution counts. +(Needed for deep recursion detection) + =item $c->error =item $c->error($error, ...) @@ -136,12 +142,26 @@ sub execute { $c->state(0); my $callsub = ( caller(1) )[3]; + my $action = ''; + if ( $c->debug ) { + $action = $c->actions->{reverse}->{"$code"}; + $action = "/$action" unless $action =~ /\-\>/; + $c->counter->{"$code"}++; + + if ( $c->counter->{"$code"} > $RECURSION ) { + my $error = qq/Deep recursion detected in "$action"/; + $c->log->error($error); + $c->error($error); + $c->state(0); + return $c->state; + } + + $action = "-> $action" if $callsub =~ /forward$/; + } + eval { if ( $c->debug ) { - my $action = $c->actions->{reverse}->{"$code"}; - $action = "/$action" unless $action =~ /\-\>/; - $action = "-> $action" if $callsub =~ /forward$/; my ( $elapsed, @state ) = $c->benchmark( $code, $class, $c, @{ $c->req->args } ); push @{ $c->{stats} }, [ $action, sprintf( '%fs', $elapsed ) ]; @@ -366,7 +386,8 @@ sub handler { my $elapsed; ( $elapsed, $status ) = $class->benchmark($handler); $elapsed = sprintf '%f', $elapsed; - my $av = sprintf '%.3f', ( $elapsed == 0 ? '??' : (1 / $elapsed) ); + my $av = sprintf '%.3f', + ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) ); my $t = Text::ASCIITable->new; $t->setCols( 'Action', 'Time' ); $t->setColWidth( 'Action', 64, 1 ); @@ -400,6 +421,7 @@ sub prepare { my ( $class, $engine ) = @_; my $c = bless { + counter => {}, request => Catalyst::Request->new( { arguments => [], @@ -679,30 +701,31 @@ Setup components. sub setup_components { my $self = shift; - - $self->components( {} ); - - my @components; - for my $component ( $self->retrieve_components ) { - - unless ( UNIVERSAL::isa( $component, 'Catalyst::Base' ) ) { - $self->components->{$component} = $component; - next; - } - my $instance; - - eval { $instance = $component->new($self) }; - - if ( $@ ) { - die( qq/Couldn't instantiate "$component", "$@"/ ); - } + # Components + my $class = ref $self || $self; + eval <<""; + package $class; + import Module::Pluggable::Fast + name => '_components', + search => [ + '$class\::Controller', '$class\::C', + '$class\::Model', '$class\::M', + '$class\::View', '$class\::V' + ]; - $self->components->{$component} = $instance; + if ( my $error = $@ ) { + chomp $error; + die qq/Couldn't load components "$error"/; + } - push @components, $component; + $self->components( {} ); + my @comps; + for my $comp ( $self->_components($self) ) { + $self->components->{ ref $comp } = $comp; + push @comps, $comp; } - + my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } ); $t->setCols('Class'); $t->setColWidth( 'Class', 75, 1 ); @@ -710,7 +733,7 @@ sub setup_components { $self->log->debug( 'Loaded components', $t->draw ) if ( @{ $t->{tbl_rows} } && $self->debug ); - $self->setup_actions( [ $self, @components ] ); + $self->setup_actions( [ $self, @comps ] ); } =item $c->state @@ -728,7 +751,7 @@ Returns a hashref containing all your data. sub stash { my $self = shift; - if ( @_ ) { + if (@_) { my $stash = @_ > 1 ? {@_} : $_[0]; while ( my ( $key, $val ) = each %$stash ) { $self->{stash}->{$key} = $val;