[freeside-commits] branch FREESIDE_4_BRANCH updated. d176b11b1730eeff8c19456c18f8e852c99fc423

Mark Wells mark at 420.am
Mon Nov 23 16:41:19 PST 2015


The branch, FREESIDE_4_BRANCH has been updated
       via  d176b11b1730eeff8c19456c18f8e852c99fc423 (commit)
       via  b6892bebffca4d2962325d9fb1a0e4c0f2bf5bec (commit)
      from  8eac4a2df15bd985c2c1192bd7fe2a74ed8937fe (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 d176b11b1730eeff8c19456c18f8e852c99fc423
Merge: b6892be 8eac4a2
Author: Mark Wells <mark at freeside.biz>
Date:   Mon Nov 23 16:31:55 2015 -0800

    Merge branch 'FREESIDE_4_BRANCH' of git.freeside.biz:/home/git/freeside into 4.x


commit b6892bebffca4d2962325d9fb1a0e4c0f2bf5bec
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..204a839 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,36 @@ 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) = @_;
+
+  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 +1119,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 +1150,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  |   61 +++++++++++++++++++++++++++++++++++++++---------------
 FS/FS/UID.pm     |   15 +++++++++-----
 htetc/handler.pl |    6 ++++++
 3 files changed, 60 insertions(+), 22 deletions(-)




More information about the freeside-commits mailing list