]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 993939: Bugzilla::User::Setting::groups() should use memcached
authorByron Jones <glob@mozilla.com>
Wed, 28 May 2014 05:53:48 +0000 (13:53 +0800)
committerByron Jones <glob@mozilla.com>
Wed, 28 May 2014 05:53:48 +0000 (13:53 +0800)
r=dkl, a=justdave

Bugzilla/Memcached.pm
Bugzilla/User.pm
editusers.cgi

index 2bf7f13937bf2445905c0435fdaf519b63a4dce7..819b6d8b6b971507fcf80e9941222dcb496a2e60 100644 (file)
@@ -104,7 +104,7 @@ sub set_config {
     return unless $self->{memcached};
 
     if (exists $args->{key}) {
-        return $self->_set($self->_config_prefix . ':' . $args->{key}, $args->{data});
+        return $self->_set($self->_config_prefix . '.' . $args->{key}, $args->{data});
     }
     else {
         ThrowCodeError('params_required', { function => "Bugzilla::Memcached::set_config",
@@ -117,7 +117,7 @@ sub get_config {
     return unless $self->{memcached};
 
     if (exists $args->{key}) {
-        return $self->_get($self->_config_prefix . ':' . $args->{key});
+        return $self->_get($self->_config_prefix . '.' . $args->{key});
     }
     else {
         ThrowCodeError('params_required', { function => "Bugzilla::Memcached::get_config",
@@ -165,9 +165,14 @@ sub clear_all {
 }
 
 sub clear_config {
-    my ($self) = @_;
-    return unless $self->{memcached};
-    $self->_inc_prefix("config");
+    my ($self, $args) = @_;
+    if ($args && exists $args->{key}) {
+        $self->_delete($self->_config_prefix . '.' . $args->{key});
+    }
+    else {
+        return unless $self->{memcached};
+        $self->_inc_prefix("config");
+    }
 }
 
 # in order to clear all our keys, we add a prefix to all our keys.  when we
@@ -214,7 +219,7 @@ sub _config_prefix {
 
 sub _encode_key {
     my ($self, $key) = @_;
-    $key = $self->_global_prefix . ':' . uri_escape_utf8($key);
+    $key = $self->_global_prefix . '.' . uri_escape_utf8($key);
     return length($self->{namespace} . $key) > MAX_KEY_LENGTH
         ? undef
         : $key;
@@ -419,6 +424,11 @@ corresponding C<table> and C<name> entry.
 Removes C<value> with the specified C<table> and C<name>, as well as the
 corresponding C<table> and C<id> entry.
 
+=item C<clear_config({ key =E<gt> $key })>
+
+Remove C<value> with the specified C<key> from the configuration cache.  See
+C<set_config> for more information.
+
 =item C<clear_config>
 
 Removes all configuration related values from the cache.  See C<set_config> for
index 0b644a3b42ea6641d46234ca28bece590a4dc2a2..6b5d13cbed39235a849a0b5dc213b800c3b87d88 100644 (file)
@@ -668,66 +668,78 @@ sub flush_queries_cache {
 sub groups {
     my $self = shift;
 
-    return $self->{groups} if defined $self->{groups};
     return [] unless $self->id;
+    return $self->{groups} if defined $self->{groups};
 
-    my $dbh = Bugzilla->dbh;
-    my $groups_to_check = $dbh->selectcol_arrayref(
-        q{SELECT DISTINCT group_id
-            FROM user_group_map
-           WHERE user_id = ? AND isbless = 0}, undef, $self->id);
-
-    my $cache_key = 'group_grant_type_' . GROUP_MEMBERSHIP;
-    my $membership_rows = Bugzilla->memcached->get_config({
-        key => $cache_key,
+    my $user_groups_key = "user_groups." . $self->id;
+    my $groups = Bugzilla->memcached->get_config({
+        key => $user_groups_key
     });
-    if (!$membership_rows) {
-        $membership_rows = $dbh->selectall_arrayref(
-            "SELECT DISTINCT grantor_id, member_id
-               FROM group_group_map
-              WHERE grant_type = " . GROUP_MEMBERSHIP);
-        Bugzilla->memcached->set_config({
-            key  => $cache_key,
-            data => $membership_rows,
+
+    if (!$groups) {
+        my $dbh = Bugzilla->dbh;
+        my $groups_to_check = $dbh->selectcol_arrayref(
+            "SELECT DISTINCT group_id
+               FROM user_group_map
+              WHERE user_id = ? AND isbless = 0", undef, $self->id);
+
+        my $grant_type_key = 'group_grant_type_' . GROUP_MEMBERSHIP;
+        my $membership_rows = Bugzilla->memcached->get_config({
+            key => $grant_type_key,
         });
-    }
+        if (!$membership_rows) {
+            $membership_rows = $dbh->selectall_arrayref(
+                "SELECT DISTINCT grantor_id, member_id
+                FROM group_group_map
+                WHERE grant_type = " . GROUP_MEMBERSHIP);
+            Bugzilla->memcached->set_config({
+                key  => $grant_type_key,
+                data => $membership_rows,
+            });
+        }
 
-    my %group_membership;
-    foreach my $row (@$membership_rows) {
-        my ($grantor_id, $member_id) = @$row; 
-        push (@{ $group_membership{$member_id} }, $grantor_id);
-    }
-    
-    # Let's walk the groups hierarchy tree (using FIFO)
-    # On the first iteration it's pre-filled with direct groups 
-    # membership. Later on, each group can add its own members into the
-    # FIFO. Circular dependencies are eliminated by checking
-    # $checked_groups{$member_id} hash values.
-    # As a result, %groups will have all the groups we are the member of.
-    my %checked_groups;
-    my %groups;
-    while (scalar(@$groups_to_check) > 0) {
-        # Pop the head group from FIFO
-        my $member_id = shift @$groups_to_check;
-        
-        # Skip the group if we have already checked it
-        if (!$checked_groups{$member_id}) {
-            # Mark group as checked
-            $checked_groups{$member_id} = 1;
-            
-            # Add all its members to the FIFO check list
-            # %group_membership contains arrays of group members 
-            # for all groups. Accessible by group number.
-            my $members = $group_membership{$member_id};
-            my @new_to_check = grep(!$checked_groups{$_}, @$members);
-            push(@$groups_to_check, @new_to_check);
-
-            $groups{$member_id} = 1;
+        my %group_membership;
+        foreach my $row (@$membership_rows) {
+            my ($grantor_id, $member_id) = @$row;
+            push (@{ $group_membership{$member_id} }, $grantor_id);
         }
-    }
 
-    $self->{groups} = Bugzilla::Group->new_from_list([keys %groups]);
+        # Let's walk the groups hierarchy tree (using FIFO)
+        # On the first iteration it's pre-filled with direct groups
+        # membership. Later on, each group can add its own members into the
+        # FIFO. Circular dependencies are eliminated by checking
+        # $checked_groups{$member_id} hash values.
+        # As a result, %groups will have all the groups we are the member of.
+        my %checked_groups;
+        my %groups;
+        while (scalar(@$groups_to_check) > 0) {
+            # Pop the head group from FIFO
+            my $member_id = shift @$groups_to_check;
+
+            # Skip the group if we have already checked it
+            if (!$checked_groups{$member_id}) {
+                # Mark group as checked
+                $checked_groups{$member_id} = 1;
+
+                # Add all its members to the FIFO check list
+                # %group_membership contains arrays of group members
+                # for all groups. Accessible by group number.
+                my $members = $group_membership{$member_id};
+                my @new_to_check = grep(!$checked_groups{$_}, @$members);
+                push(@$groups_to_check, @new_to_check);
+
+                $groups{$member_id} = 1;
+            }
+        }
+        $groups = [ keys %groups ];
 
+        Bugzilla->memcached->set_config({
+            key  => $user_groups_key,
+            data => $groups,
+        });
+    }
+
+    $self->{groups} = Bugzilla::Group->new_from_list($groups);
     return $self->{groups};
 }
 
@@ -1448,6 +1460,8 @@ sub derive_regexp_groups {
             $group_delete->execute($id, $group, GRANT_REGEXP) if $present;
         }
     }
+
+    Bugzilla->memcached->clear_config({ key => "user_groups.$id" });
 }
 
 sub product_responsibilities {
index 83f364528f326bd8815484870fd0a5a71faa2f2d..650784d5dce41ec07b0f415c56bcb3a2bddb4a36 100755 (executable)
@@ -346,6 +346,7 @@ if ($action eq 'search') {
                  ($otherUserID, $userid,
                   get_field_id('bug_group'),
                   join(', ', @groupsRemovedFrom), join(', ', @groupsAddedTo)));
+        Bugzilla->memcached->clear_config({ key => "user_groups.$otherUserID" })
     }
     # XXX: should create profiles_activity entries for blesser changes.