Commit 6d730fae authored by Byron Jones's avatar Byron Jones

Bug 993939: Bugzilla::User::Setting::groups() should use memcached

r=dkl, a=justdave
parent ccff2482
...@@ -104,7 +104,7 @@ sub set_config { ...@@ -104,7 +104,7 @@ sub set_config {
return unless $self->{memcached}; return unless $self->{memcached};
if (exists $args->{key}) { 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 { else {
ThrowCodeError('params_required', { function => "Bugzilla::Memcached::set_config", ThrowCodeError('params_required', { function => "Bugzilla::Memcached::set_config",
...@@ -117,7 +117,7 @@ sub get_config { ...@@ -117,7 +117,7 @@ sub get_config {
return unless $self->{memcached}; return unless $self->{memcached};
if (exists $args->{key}) { if (exists $args->{key}) {
return $self->_get($self->_config_prefix . ':' . $args->{key}); return $self->_get($self->_config_prefix . '.' . $args->{key});
} }
else { else {
ThrowCodeError('params_required', { function => "Bugzilla::Memcached::get_config", ThrowCodeError('params_required', { function => "Bugzilla::Memcached::get_config",
...@@ -165,9 +165,14 @@ sub clear_all { ...@@ -165,9 +165,14 @@ sub clear_all {
} }
sub clear_config { sub clear_config {
my ($self) = @_; my ($self, $args) = @_;
return unless $self->{memcached}; if ($args && exists $args->{key}) {
$self->_inc_prefix("config"); $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 # in order to clear all our keys, we add a prefix to all our keys. when we
...@@ -214,7 +219,7 @@ sub _config_prefix { ...@@ -214,7 +219,7 @@ sub _config_prefix {
sub _encode_key { sub _encode_key {
my ($self, $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 return length($self->{namespace} . $key) > MAX_KEY_LENGTH
? undef ? undef
: $key; : $key;
...@@ -419,6 +424,11 @@ corresponding C<table> and C<name> entry. ...@@ -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 Removes C<value> with the specified C<table> and C<name>, as well as the
corresponding C<table> and C<id> entry. 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> =item C<clear_config>
Removes all configuration related values from the cache. See C<set_config> for Removes all configuration related values from the cache. See C<set_config> for
......
...@@ -668,66 +668,78 @@ sub flush_queries_cache { ...@@ -668,66 +668,78 @@ sub flush_queries_cache {
sub groups { sub groups {
my $self = shift; my $self = shift;
return $self->{groups} if defined $self->{groups};
return [] unless $self->id; return [] unless $self->id;
return $self->{groups} if defined $self->{groups};
my $dbh = Bugzilla->dbh; my $user_groups_key = "user_groups." . $self->id;
my $groups_to_check = $dbh->selectcol_arrayref( my $groups = Bugzilla->memcached->get_config({
q{SELECT DISTINCT group_id key => $user_groups_key
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,
}); });
if (!$membership_rows) {
$membership_rows = $dbh->selectall_arrayref( if (!$groups) {
"SELECT DISTINCT grantor_id, member_id my $dbh = Bugzilla->dbh;
FROM group_group_map my $groups_to_check = $dbh->selectcol_arrayref(
WHERE grant_type = " . GROUP_MEMBERSHIP); "SELECT DISTINCT group_id
Bugzilla->memcached->set_config({ FROM user_group_map
key => $cache_key, WHERE user_id = ? AND isbless = 0", undef, $self->id);
data => $membership_rows,
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; my %group_membership;
foreach my $row (@$membership_rows) { foreach my $row (@$membership_rows) {
my ($grantor_id, $member_id) = @$row; my ($grantor_id, $member_id) = @$row;
push (@{ $group_membership{$member_id} }, $grantor_id); 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;
} }
}
$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}; return $self->{groups};
} }
...@@ -1448,6 +1460,8 @@ sub derive_regexp_groups { ...@@ -1448,6 +1460,8 @@ sub derive_regexp_groups {
$group_delete->execute($id, $group, GRANT_REGEXP) if $present; $group_delete->execute($id, $group, GRANT_REGEXP) if $present;
} }
} }
Bugzilla->memcached->clear_config({ key => "user_groups.$id" });
} }
sub product_responsibilities { sub product_responsibilities {
......
...@@ -346,6 +346,7 @@ if ($action eq 'search') { ...@@ -346,6 +346,7 @@ if ($action eq 'search') {
($otherUserID, $userid, ($otherUserID, $userid,
get_field_id('bug_group'), get_field_id('bug_group'),
join(', ', @groupsRemovedFrom), join(', ', @groupsAddedTo))); join(', ', @groupsRemovedFrom), join(', ', @groupsAddedTo)));
Bugzilla->memcached->clear_config({ key => "user_groups.$otherUserID" })
} }
# XXX: should create profiles_activity entries for blesser changes. # XXX: should create profiles_activity entries for blesser changes.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment