You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by ma...@sergeant.org on 2006/08/24 02:02:18 UTC

[SVN] [112] effectively memoize hooks to improve performance

Revision: 112
Author:   matt
Date:     2006-08-24 00:01:51 +0000 (Thu, 24 Aug 2006)

Log Message:
-----------
effectively memoize hooks to improve performance

Modified Paths:
--------------
    trunk/lib/AxKit2/Client.pm

Modified: trunk/lib/AxKit2/Client.pm
===================================================================
--- trunk/lib/AxKit2/Client.pm	2006-08-23 16:55:00 UTC (rev 111)
+++ trunk/lib/AxKit2/Client.pm	2006-08-24 00:01:51 UTC (rev 112)
@@ -99,14 +99,21 @@
     
     my $conf = $self->config();
     
+    # Logging hooks called at config parse time, so can't cache them
+    if ($hook ne "logging") {
+        if (my $cached_hooks = $conf->notes("cached_hooks_$hook")) {
+            return $self->_run_hooks($conf, $hook, [@_], $cached_hooks, 0);
+        }
+    }
+    
     my @hooks;
-  MAINLOOP:
     for my $plugin ($conf->plugins) {
         my $plug = $PLUGINS{$plugin} || next;
         push @hooks, map { [$plugin, $plug, $_] } $plug->hooks($hook);
     }
     
-    $self->_run_hooks($hook, [@_], \@hooks);
+    $conf->notes("cached_hooks_$hook", \@hooks);
+    $self->_run_hooks($conf, $hook, [@_], \@hooks, 0);
 }
 
 sub finish_continuation {
@@ -116,34 +123,40 @@
     $self->{continuation} = undef;
     my $hook = shift @$todo;
     my $args = shift @$todo;
-    $self->_run_hooks($hook, $args, $todo);
+    my $pos  = shift @$todo;
+    my $conf = $self->config;
+    my $hooks = $conf->notes("cached_hooks_$hook");
+    $self->_run_hooks($conf, $hook, $args, $hooks, $pos+1);
 }
 
 sub _run_hooks {
     my $self = shift;
-    my ($hook, $args, $todo) = @_;
+    my ($conf, $hook, $args, $hooks, $pos) = @_;
     
-    my $conf = $self->config();
+    my $last_hook = $#$hooks;
     
     my @r;
-    while (@$todo) {
-        my $info = shift @$todo;
-        my ($plugin, $plug, $h) = @$info;
-        $self->log(LOGDEBUG, "$plugin running hook $hook") unless $hook eq 'logging';
-        eval { @r = $plug->$h($self, $conf, @$args) };
-        if ($@) {
-            my $err = $@;
-            $self->log(LOGERROR, "FATAL PLUGIN ERROR: $err");
-            $self->hook_error($err);
-            return DONE;
+    if ($pos <= $last_hook) {
+        for my $idx ($pos .. $last_hook) {
+            my $info = $hooks->[$idx];
+            my ($plugin, $plug, $h) = @$info;
+            # $self->log(LOGDEBUG, "$plugin ($idx) running hook $hook") unless $hook eq 'logging';
+            eval { @r = $plug->$h($self, $conf, @$args) };
+            if ($@) {
+                my $err = $@;
+                $self->log(LOGERROR, "FATAL PLUGIN ERROR: $err");
+                $self->hook_error($err);
+                return DONE;
+            }
+            next unless @r;
+            if ($r[0] == CONTINUATION) {
+                $self->pause_read();
+                $self->{continuation} = [$hook, $args, $idx];
+            }
+            last unless $r[0] == DECLINED;
         }
-        next unless @r;
-        if ($r[0] == CONTINUATION) {
-            $self->pause_read();
-            $self->{continuation} = [$hook, $args, @$todo];
-        }
-        last unless $r[0] == DECLINED;
     }
+    
     $r[0] = DECLINED if not defined $r[0];
     if ($r[0] != CONTINUATION) {
         my $responder = "hook_${hook}_end";
@@ -345,7 +358,7 @@
     }
     elsif ($ret == OK) {
         $out->output($self) if $out;
-        $self->write(sub { $self->http_response_sent() });
+        $self->write(sub { $self->http_response_sent($self->headers_out->response_code) });
     }
     else {
         $self->default_error_out($ret);