[Rt-commit] rt branch, 4.2/user_preferences_cache, created. rt-4.0.0rc4-80-gddfeca8

Ruslan Zakirov ruz at bestpractical.com
Tue Feb 15 18:06:54 EST 2011


The branch, 4.2/user_preferences_cache has been created
        at  ddfeca8e69432680335eba7964f2771b77f7f3dc (commit)

- Log -----------------------------------------------------------------
commit ddfeca8e69432680335eba7964f2771b77f7f3dc
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Feb 16 02:03:02 2011 +0300

    cache user preferences
    
    we use LoadByCols which is cacheable, however it doesn't cache
    negative hits. More and more Config options are overridable and
    may be stored in DB, however often users use system's default.
    Use our own cache to avoid constant queries for records that are
    not there.

diff --git a/lib/RT/Attribute.pm b/lib/RT/Attribute.pm
index 26589b6..6dcc38c 100644
--- a/lib/RT/Attribute.pm
+++ b/lib/RT/Attribute.pm
@@ -181,7 +181,9 @@ sub Create {
         $args{'ContentType'} = 'storable';
     }
 
-    
+    delete $RT::User::PREFERENCES_CACHE{ $args{'ObjectId'} }{ $args{'Name'} }
+        if $args{'ObjectType'} eq 'RT::User';
+
     $self->SUPER::Create(
                          Name => $args{'Name'},
                          Content => $args{'Content'},
@@ -276,6 +278,11 @@ sub SetContent {
     my $self = shift;
     my $content = shift;
 
+    if ( $self->__Value('ObjectType') eq 'RT::User' ) {
+        delete $RT::User::PREFERENCES_CACHE
+            { $self->__Value('ObjectId') }{ $self->__Value('Name') };
+    }
+
     # Call __Value to avoid ACL check.
     if ( ($self->__Value('ContentType')||'') eq 'storable' ) {
         # We eval the serialization because it will lose on a coderef.
diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm
index 67fcb13..ba4a369 100644
--- a/lib/RT/Interface/Web/Handler.pm
+++ b/lib/RT/Interface/Web/Handler.pm
@@ -190,6 +190,7 @@ sub CleanupRequest {
     }
 
     %RT::Ticket::MERGE_CACHE = ( effective => {}, merged => {} );
+    %RT::User::PREFERENCES_CACHE = ();
 
     # RT::System persists between requests, so its attributes cache has to be
     # cleared manually. Without this, for example, subject tags across multiple
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 40855bd..ab583d8 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -1262,7 +1262,7 @@ sub _PrefName {
         $name = ref($name).'-'.$name->Id;
     }
 
-    return 'Pref-'.$name;
+    return 'Pref-'. $name;
 }
 
 =head2 Preferences NAME/OBJ DEFAULT
@@ -1273,15 +1273,24 @@ override the entries with user preferences.
 
 =cut
 
+our %PREFERENCES_CACHE = ();
+
 sub Preferences {
     my $self  = shift;
-    my $name = _PrefName (shift);
+    my $name = _PrefName(shift);
     my $default = shift;
 
-    my $attr = RT::Attribute->new( $self->CurrentUser );
-    $attr->LoadByNameAndObject( Object => $self, Name => $name );
+    my $content;
+    if ( exists $PREFERENCES_CACHE{ $self->id }{ $name } ) {
+        $content = $PREFERENCES_CACHE{ $self->id }{ $name };
+    }
+    else {
+        my $attr = RT::Attribute->new( $self->CurrentUser );
+        $attr->LoadByNameAndObject( Object => $self, Name => $name );
+        $PREFERENCES_CACHE{ $self->id }{ $name } = $content
+            = $attr->Id ? $attr->Content : undef;
+    }
 
-    my $content = $attr->Id ? $attr->Content : undef;
     unless ( ref $content eq 'HASH' ) {
         return defined $content ? $content : $default;
     }
@@ -1291,7 +1300,7 @@ sub Preferences {
             exists $content->{$_} or $content->{$_} = $default->{$_};
         }
     } elsif (defined $default) {
-        $RT::Logger->error("Preferences $name for user".$self->Id." is hash but default is not");
+        $RT::Logger->error("Preferences $name for user #".$self->Id." is hash but default is not");
     }
     return $content;
 }
@@ -1310,6 +1319,8 @@ sub SetPreferences {
     return (0, $self->loc("No permission to set preferences"))
         unless $self->CurrentUserCanModify('Preferences');
 
+    # we clear cache in RT::Attribute
+
     my $attr = RT::Attribute->new( $self->CurrentUser );
     $attr->LoadByNameAndObject( Object => $self, Name => $name );
     if ( $attr->Id ) {

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


More information about the Rt-commit mailing list