improved req/res/stats trait composing
John Napiorkowski [Wed, 8 Jun 2016 14:34:48 +0000 (09:34 -0500)]
Changes
lib/Catalyst.pm
t/class_traits.t

diff --git a/Changes b/Changes
index c634d3a..3ea3fae 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,11 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+5.90105 - 2016-07-08
+  - Tweak some test cases to try and prevent them from failing in limited cases.
+  - Changed how we compose traits onto the response, request, and stats class so
+    that we compose just once at setup time (performance optimization).  Also added
+    a debug screen at startup to display composed classes to help with debugging.
+
 5.90104 - 2016-04-04
   - Merged pull request #131, fix for noisy debug logs when used type constraints
     in your actions.  Additional changes to the developer debug screen output to
index 602316a..27d053c 100644 (file)
@@ -81,6 +81,8 @@ sub _build_request_constructor_args {
 
 sub composed_request_class {
   my $class = shift;
+  return $class->_composed_request_class if $class->_composed_request_class;
+
   my @traits = (@{$class->request_class_traits||[]}, @{$class->config->{request_class_traits}||[]});
 
   # For each trait listed, figure out what the namespace is.  First we try the $trait
@@ -92,8 +94,14 @@ sub composed_request_class {
     Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_)
   } @traits;
 
-  return $class->_composed_request_class ||
-    $class->_composed_request_class(Moose::Util::with_traits($class->request_class, @normalized_traits));
+  if ($class->debug && scalar(@normalized_traits)) {
+      my $column_width = Catalyst::Utils::term_width() - 6;
+      my $t = Text::SimpleTable->new($column_width);
+      $t->row($_) for @normalized_traits;
+      $class->log->debug( "Composed Request Class Traits:\n" . $t->draw . "\n" );
+  }
+
+  return $class->_composed_request_class(Moose::Util::with_traits($class->request_class, @normalized_traits));
 }
 
 has response => (
@@ -115,6 +123,8 @@ sub _build_response_constructor_args {
 
 sub composed_response_class {
   my $class = shift;
+  return $class->_composed_response_class if $class->_composed_response_class;
+  
   my @traits = (@{$class->response_class_traits||[]}, @{$class->config->{response_class_traits}||[]});
 
   my $trait_ns = 'TraitFor::Response';
@@ -122,8 +132,14 @@ sub composed_response_class {
     Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_)
   } @traits;
 
-  return $class->_composed_response_class ||
-    $class->_composed_response_class(Moose::Util::with_traits($class->response_class, @normalized_traits));
+  if ($class->debug && scalar(@normalized_traits)) {
+      my $column_width = Catalyst::Utils::term_width() - 6;
+      my $t = Text::SimpleTable->new($column_width);
+      $t->row($_) for @normalized_traits;
+      $class->log->debug( "Composed Response Class Traits:\n" . $t->draw . "\n" );
+  }
+
+  return $class->_composed_response_class(Moose::Util::with_traits($class->response_class, @normalized_traits));
 }
 
 has namespace => (is => 'rw');
@@ -166,6 +182,8 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 sub composed_stats_class {
   my $class = shift;
+  return $class->_composed_stats_class if $class->_composed_stats_class;
+
   my @traits = (@{$class->stats_class_traits||[]}, @{$class->config->{stats_class_traits}||[]});
 
   my $trait_ns = 'TraitFor::Stats';
@@ -173,8 +191,14 @@ sub composed_stats_class {
     Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_)
   } @traits;
 
-  return $class->_composed_stats_class ||
-    $class->_composed_stats_class(Moose::Util::with_traits($class->stats_class, @normalized_traits));
+  if ($class->debug && scalar(@normalized_traits)) {
+      my $column_width = Catalyst::Utils::term_width() - 6;
+      my $t = Text::SimpleTable->new($column_width);
+      $t->row($_) for @normalized_traits;
+      $class->log->debug( "Composed Stats Class Traits:\n" . $t->draw . "\n" );
+  }
+
+  return $class->_composed_stats_class(Moose::Util::with_traits($class->stats_class, @normalized_traits));
 }
 
 __PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC);
@@ -1396,6 +1420,11 @@ EOF
     $class->setup_encoding();
     $class->setup_middleware();
 
+    # call these so we pre setup the composed classes
+    $class->composed_request_class;
+    $class->composed_response_class;
+    $class->composed_stats_class;
+
     # Initialize our data structure
     $class->components( {} );
 
index 8c65b38..2f6e4f3 100644 (file)
@@ -5,27 +5,34 @@ use Class::MOP;
 
 BEGIN {
   package TestRole;
+  $INC{'TestRole'} = __FILE__;
   use Moose::Role;
 
   sub a { 'a' }
   sub b { 'b' }
 
   package Catalyst::TraitFor::Request::Foo;
+  $INC{'Catalyst/TraitFor/Request/Foo.pm'} = __FILE__;
   use Moose::Role;
 
   sub c { 'c' }
 
   package TestApp::TraitFor::Request::Bar;
+  $INC{'Catalyst/TraitFor/Request/Bar.pm'} = __FILE__;
   use Moose::Role;
 
   sub d { 'd' }
 
   package Catalyst::TraitFor::Response::Foo;
+  $INC{'Catalyst/TraitFor/Response/Foo.pm'} = __FILE__;
+
   use Moose::Role;
 
   sub c { 'c' }
 
-  package TestApp::TraitFor::Response::Bar;
+  package TestApp::TraitFor::Response::Bar; 
+  $INC{'Catalyst/TraitFor/Response/Bar.pm'} = __FILE__;
+
   use Moose::Role;
 
   sub d { 'd' }
@@ -33,6 +40,7 @@ BEGIN {
  
 {
   package TestApp;
+  $INC{'TestApp.pm'} = __FILE__;
  
   use Catalyst;