[freeside-commits] branch master updated. 63cc43a59cf31b1d2f48c9bbdd0d87afd7bccb4d

Mark Wells mark at 420.am
Mon Nov 23 14:13:30 PST 2015


The branch, master has been updated
       via  63cc43a59cf31b1d2f48c9bbdd0d87afd7bccb4d (commit)
      from  2556ee7497c7684b75eca0061457d21b9b315dc1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 63cc43a59cf31b1d2f48c9bbdd0d87afd7bccb4d
Author: Mark Wells <mark at freeside.biz>
Date:   Mon Nov 23 14:12:04 2015 -0800

    Cache foreign key method lookup for better performance.
    
    Contributed by Jason Terry <jterry at bluehost.com>

diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index fafceac..827e407 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -3,7 +3,7 @@ use base qw( Exporter );
 
 use strict;
 use vars qw( $AUTOLOAD
-             %virtual_fields_cache %fk_method_cache
+             %virtual_fields_cache %fk_method_cache $fk_table_cache
              $money_char $lat_lower $lon_upper
            );
 use Carp qw(carp cluck croak confess);
@@ -34,7 +34,7 @@ our @EXPORT_OK = qw(
   dbh fields hfields qsearch qsearchs dbdef jsearch
   str2time_sql str2time_sql_closing regexp_sql not_regexp_sql
   concat_sql group_concat_sql
-  midnight_sql
+  midnight_sql fk_methods_init
 );
 
 our $DEBUG = 0;
@@ -82,9 +82,7 @@ FS::UID->install_callback( sub {
     eval "sub PG_BYTEA { die 'guru meditation #9: calling PG_BYTEA when not running Pg?'; }";
   }
 
-  foreach my $table ( dbdef->tables ) {
-    $fk_method_cache{$table} = fk_methods($table);
-  }
+  #fk_methods_init();
 
 } );
 
@@ -988,7 +986,7 @@ sub exists {
   exists($self->{Hash}->{$field});
 }
 
-=item AUTLOADED METHODS
+=item AUTOLOADED METHODS
 
 $record->column is a synonym for $record->get('column');
 
@@ -1010,10 +1008,8 @@ sub AUTOLOAD {
   confess "errant AUTOLOAD $field for $self (arg $value)"
     unless blessed($self) && $self->can('setfield');
 
-  #$fk_method_cache{$self->table} ||= fk_methods($self->table);
-  if ( exists($fk_method_cache{$self->table}->{$field}) ) {
+  if ( my $fk_info = get_fk_method($self->table, $field) ) {
 
-    my $fk_info = $fk_method_cache{$self->table}->{$field};
     my $method = $fk_info->{method} || 'qsearchs';
     my $table = $fk_info->{table} || $field;
     my $column = $fk_info->{column};
@@ -1056,6 +1052,37 @@ sub AUTOLOAD {
 #  }    
 #}
 
+# get_fk_method(TABLE, FIELD)
+# Internal subroutine for fetching the foreign key descriptor for TABLE.FIELD
+# if there is one. If not, returns undef.
+# This will initialize fk_method_cache if it hasn't happened yet. It is the
+# _only_ allowed way to access the contents of %fk_method_cache.
+
+# if we wanted to be even more efficient we'd create the fk methods in the
+# symbol table instead of relying on AUTOLOAD every time
+
+sub get_fk_method {
+  my ($table, $field) = @_;
+
+  # maybe should only load one table at a time?
+  fk_methods_init() unless exists($fk_method_cache{$table});
+
+  if ( exists($fk_method_cache{$table}) and
+       exists($fk_method_cache{$table}{$field}) ) {
+    return $fk_method_cache{$table}{$field};
+  } else {
+    return undef;
+  }
+
+}
+
+sub fk_methods_init {
+  warn "[fk_methods_init]\n";
+  foreach my $table ( dbdef->tables ) {
+    $fk_method_cache{$table} = fk_methods($table);
+  }
+}
+
 sub fk_methods {
   my $table = shift;
 
@@ -1093,11 +1120,15 @@ sub fk_methods {
   #  (alas.  why we're cached.  still, might this loop better be done once at
   #   schema load time insetad of every time we AUTOLOAD a method on a new
   #   class?)
-  foreach my $f_table ( dbdef->tables ) {
-    foreach my $fk (dbdef->table($f_table)->foreign_keys) {
-
-      next unless $fk->table eq $table;
-
+  if (! defined $fk_table_cache) {
+    foreach my $f_table ( dbdef->tables ) {
+      foreach my $fk (dbdef->table($f_table)->foreign_keys) {
+        push @{$fk_table_cache->{$fk->table}},[$f_table,$fk];
+      }
+    }
+  }
+  foreach my $fks (@{$fk_table_cache->{$table}}) {
+      my ($f_table,$fk) = @$fks;
       my $method = '';
       if ( scalar( @{$fk->columns} ) == 1 ) {
         if (    ! defined($fk->references)
@@ -1120,9 +1151,6 @@ sub fk_methods {
         }
 
       }
-
-    }
-
   }
 
   \%hash;
diff --git a/FS/FS/UID.pm b/FS/FS/UID.pm
index c725f03..50a9178 100644
--- a/FS/FS/UID.pm
+++ b/FS/FS/UID.pm
@@ -14,7 +14,7 @@ use IO::File;
 use FS::CurrentUser;
 
 @EXPORT_OK = qw( checkeuid checkruid cgi setcgi adminsuidsetup forksuidsetup
-                 preuser_setup
+                 preuser_setup load_schema
                  getotaker dbh datasrc getsecrets driver_name myconnect
                );
 
@@ -113,6 +113,14 @@ sub env_setup {
 
 }
 
+sub load_schema {
+  warn "$me loading schema\n" if $DEBUG;
+  getsecrets() unless $datasrc;
+  use FS::Schema qw(reload_dbdef dbdef);
+  reload_dbdef("$conf_dir/dbdef.$datasrc")
+    unless $FS::Schema::setup_hack;
+}
+
 sub db_setup {
   croak "Not running uid freeside (\$>=$>, \$<=$<)\n" unless checkeuid();
 
@@ -121,10 +129,7 @@ sub db_setup {
 
   warn "$me forksuidsetup connected to database with handle $dbh\n" if $DEBUG;
 
-  warn "$me forksuidsetup loading schema\n" if $DEBUG;
-  use FS::Schema qw(reload_dbdef dbdef);
-  reload_dbdef("$conf_dir/dbdef.$datasrc")
-    unless $FS::Schema::setup_hack;
+  load_schema();
 
   warn "$me forksuidsetup deciding upon config system to use\n" if $DEBUG;
 
diff --git a/htetc/handler.pl b/htetc/handler.pl
index 416ea69..4bb214c 100644
--- a/htetc/handler.pl
+++ b/htetc/handler.pl
@@ -10,6 +10,12 @@ use FS::Conf;
 
 $FS::Conf::conf_cache_enabled = 1; # enable FS::Conf caching for performance
 
+# Preload to share in mod_perl parent for performance
+use FS::UID qw(load_schema);
+load_schema();
+use FS::Record qw(fk_methods_init);
+fk_methods_init;
+
 if ( %%%RT_ENABLED%%% ) {
 
   require RT;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Record.pm  |   62 +++++++++++++++++++++++++++++++++++++++---------------
 FS/FS/UID.pm     |   15 ++++++++-----
 htetc/handler.pl |    6 ++++++
 3 files changed, 61 insertions(+), 22 deletions(-)




More information about the freeside-commits mailing list