Commit c5464b5b authored by Byron Jones's avatar Byron Jones

Bug 956233: enable USE_MEMCACHE on most objects

r=dkl, a=glob
parent cbd65065
...@@ -908,6 +908,9 @@ sub update { ...@@ -908,6 +908,9 @@ sub update {
$dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?', $dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?',
undef, ($timestamp, $self->bug_id)); undef, ($timestamp, $self->bug_id));
$self->{modification_time} = $timestamp; $self->{modification_time} = $timestamp;
# because we updated the attachments table after SUPER::update(), we
# need to ensure the cache is flushed.
Bugzilla->memcached->clear({ table => 'attachments', id => $self->id });
} }
return $changes; return $changes;
...@@ -932,7 +935,10 @@ sub remove_from_db { ...@@ -932,7 +935,10 @@ sub remove_from_db {
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
$dbh->bz_start_transaction(); $dbh->bz_start_transaction();
$dbh->do('DELETE FROM flags WHERE attach_id = ?', undef, $self->id); my @flag_ids = $dbh->selectrow_array(
'SELECT id FROM flags WHERE attach_id = ?', undef, $self->id);
$dbh->do('DELETE FROM flags WHERE ' . $dbh->sql_in('id', \@flag_ids))
if @flag_ids;
$dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $self->id); $dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $self->id);
$dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ? $dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ?
WHERE attach_id = ?', undef, ('text/plain', 0, 1, $self->id)); WHERE attach_id = ?', undef, ('text/plain', 0, 1, $self->id));
...@@ -942,6 +948,13 @@ sub remove_from_db { ...@@ -942,6 +948,13 @@ sub remove_from_db {
if (-e $filename) { if (-e $filename) {
unlink $filename or warn "Couldn't unlink $filename: $!"; unlink $filename or warn "Couldn't unlink $filename: $!";
} }
# As we don't call SUPER->remove_from_db we need to manually clear
# memcached here.
Bugzilla->memcached->clear({ table => 'attachments', id => $self->id });
foreach my $flag_id (@flag_ids) {
Bugzilla->memcached->clear({ table => 'flags', id => $flag_id });
}
} }
############################### ###############################
......
...@@ -89,6 +89,7 @@ sub create_or_update_user { ...@@ -89,6 +89,7 @@ sub create_or_update_user {
if ($extern_id && $username_user_id && !$extern_user_id) { if ($extern_id && $username_user_id && !$extern_user_id) {
$dbh->do('UPDATE profiles SET extern_id = ? WHERE userid = ?', $dbh->do('UPDATE profiles SET extern_id = ? WHERE userid = ?',
undef, $extern_id, $username_user_id); undef, $extern_id, $username_user_id);
Bugzilla->memcached->clear({ table => 'profiles', id => $username_user_id });
} }
# Finally, at this point, one of these will give us a valid user id. # Finally, at this point, one of these will give us a valid user id.
......
...@@ -95,6 +95,7 @@ sub change_password { ...@@ -95,6 +95,7 @@ sub change_password {
my $cryptpassword = bz_crypt($password); my $cryptpassword = bz_crypt($password);
$dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?", $dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?",
undef, $cryptpassword, $user->id); undef, $cryptpassword, $user->id);
Bugzilla->memcached->clear({ table => 'profiles', id => $user->id });
} }
1; 1;
...@@ -54,6 +54,8 @@ use constant LIST_ORDER => ID_FIELD; ...@@ -54,6 +54,8 @@ use constant LIST_ORDER => ID_FIELD;
# Bugs have their own auditing table, bugs_activity. # Bugs have their own auditing table, bugs_activity.
use constant AUDIT_CREATES => 0; use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0; use constant AUDIT_UPDATES => 0;
# This will be enabled later
use constant USE_MEMCACHED => 0;
# This is a sub because it needs to call other subroutines. # This is a sub because it needs to call other subroutines.
sub DB_COLUMNS { sub DB_COLUMNS {
......
...@@ -55,9 +55,18 @@ sub remove_from_db { ...@@ -55,9 +55,18 @@ sub remove_from_db {
ThrowUserError("classification_not_deletable") if ($self->id == 1); ThrowUserError("classification_not_deletable") if ($self->id == 1);
$dbh->bz_start_transaction(); $dbh->bz_start_transaction();
# Reclassify products to the default classification, if needed. # Reclassify products to the default classification, if needed.
$dbh->do("UPDATE products SET classification_id = 1 my @product_ids = $dbh->selectrow_array(
WHERE classification_id = ?", undef, $self->id); "SELECT id FROM products WHERE classification_id = ?",
undef, $self->id);
if (@product_ids) {
$dbh->do("UPDATE products SET classification_id = 1 WHERE " .
$dbh->sql_in('id', \@product_ids));
foreach my $id (@product_ids) {
Bugzilla->memcached->clear({ table => 'products', id => $id });
}
}
$self->SUPER::remove_from_db(); $self->SUPER::remove_from_db();
......
...@@ -35,6 +35,9 @@ use constant NAME_FIELD => 'tag'; ...@@ -35,6 +35,9 @@ use constant NAME_FIELD => 'tag';
use constant LIST_ORDER => 'weight DESC'; use constant LIST_ORDER => 'weight DESC';
use constant VALIDATORS => { }; use constant VALIDATORS => { };
# There's no gain to caching these objects
use constant USE_MEMCACHED => 0;
sub tag { return $_[0]->{'tag'} } sub tag { return $_[0]->{'tag'} }
sub weight { return $_[0]->{'weight'} } sub weight { return $_[0]->{'weight'} }
......
...@@ -1075,6 +1075,8 @@ sub create { ...@@ -1075,6 +1075,8 @@ sub create {
# Restore the original obsolete state of the custom field. # Restore the original obsolete state of the custom field.
$dbh->do('UPDATE fielddefs SET obsolete = 0 WHERE id = ?', undef, $field->id) $dbh->do('UPDATE fielddefs SET obsolete = 0 WHERE id = ?', undef, $field->id)
unless $is_obsolete; unless $is_obsolete;
Bugzilla->memcached->clear({ table => 'fielddefs', id => $field->id });
} }
return $field; return $field;
......
...@@ -461,6 +461,7 @@ sub update { ...@@ -461,6 +461,7 @@ sub update {
$dbh->do('UPDATE flags SET modification_date = ? WHERE id = ?', $dbh->do('UPDATE flags SET modification_date = ? WHERE id = ?',
undef, ($timestamp, $self->id)); undef, ($timestamp, $self->id));
$self->{'modification_date'} = format_time($timestamp, '%Y.%m.%d %T'); $self->{'modification_date'} = format_time($timestamp, '%Y.%m.%d %T');
Bugzilla->memcached->clear({ table => 'flags', id => $self->id });
} }
return $changes; return $changes;
} }
...@@ -607,6 +608,7 @@ sub force_retarget { ...@@ -607,6 +608,7 @@ sub force_retarget {
if ($is_retargetted) { if ($is_retargetted) {
$dbh->do('UPDATE flags SET type_id = ? WHERE id = ?', $dbh->do('UPDATE flags SET type_id = ? WHERE id = ?',
undef, ($flag->type_id, $flag->id)); undef, ($flag->type_id, $flag->id));
Bugzilla->memcached->clear({ table => 'flags', id => $flag->id });
} }
else { else {
# Track deleted attachment flags. # Track deleted attachment flags.
......
...@@ -185,8 +185,13 @@ sub update { ...@@ -185,8 +185,13 @@ sub update {
# Silently remove requestees from flags which are no longer # Silently remove requestees from flags which are no longer
# specifically requestable. # specifically requestable.
if (!$self->is_requesteeble) { if (!$self->is_requesteeble) {
$dbh->do('UPDATE flags SET requestee_id = NULL WHERE type_id = ?', my @ids = $dbh->selectrow_array(
undef, $self->id); "SELECT id FROM flags WHERE type_id = ?", undef, $self->id);
$dbh->do("UPDATE flags SET requestee_id = NULL WHERE "
. $dbh->sql_in('type_id', \@ids));
foreach my $id (@ids) {
Bugzilla->memcached->clear({ table => 'flags', id => $id });
}
} }
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
......
...@@ -397,6 +397,12 @@ sub OPTIONAL_MODULES { ...@@ -397,6 +397,12 @@ sub OPTIONAL_MODULES {
# memcached # memcached
{ {
package => 'URI-Escape',
module => 'URI::Escape',
version => 0,
feature => ['memcached'],
},
{
package => 'Cache-Memcached', package => 'Cache-Memcached',
module => 'Cache::Memcached', module => 'Cache::Memcached',
version => '0', version => '0',
......
...@@ -14,6 +14,10 @@ use warnings; ...@@ -14,6 +14,10 @@ use warnings;
use Bugzilla::Error; use Bugzilla::Error;
use Bugzilla::Util qw(trick_taint); use Bugzilla::Util qw(trick_taint);
use Scalar::Util qw(blessed); use Scalar::Util qw(blessed);
use URI::Escape;
# memcached keys have a maximum length of 250 bytes
use constant MAX_KEY_LENGTH => 250;
sub _new { sub _new {
my $invocant = shift; my $invocant = shift;
...@@ -26,10 +30,11 @@ sub _new { ...@@ -26,10 +30,11 @@ sub _new {
&& Bugzilla->params->{memcached_servers}) && Bugzilla->params->{memcached_servers})
{ {
require Cache::Memcached; require Cache::Memcached;
$self->{namespace} = Bugzilla->params->{memcached_namespace} || '';
$self->{memcached} = $self->{memcached} =
Cache::Memcached->new({ Cache::Memcached->new({
servers => [ split(/[, ]+/, Bugzilla->params->{memcached_servers}) ], servers => [ split(/[, ]+/, Bugzilla->params->{memcached_servers}) ],
namespace => Bugzilla->params->{memcached_namespace} || '', namespace => $self->{namespace},
}); });
} }
return bless($self, $class); return bless($self, $class);
...@@ -155,6 +160,14 @@ sub _prefix { ...@@ -155,6 +160,14 @@ sub _prefix {
return $request_cache->{memcached_prefix}; return $request_cache->{memcached_prefix};
} }
sub _encode_key {
my ($self, $key) = @_;
$key = $self->_prefix . ':' . uri_escape_utf8($key);
return length($self->{namespace} . $key) > MAX_KEY_LENGTH
? undef
: $key;
}
sub _set { sub _set {
my ($self, $key, $value) = @_; my ($self, $key, $value) = @_;
if (blessed($value)) { if (blessed($value)) {
...@@ -162,13 +175,17 @@ sub _set { ...@@ -162,13 +175,17 @@ sub _set {
ThrowCodeError('param_invalid', { function => "Bugzilla::Memcached::set", ThrowCodeError('param_invalid', { function => "Bugzilla::Memcached::set",
param => "value" }); param => "value" });
} }
return $self->{memcached}->set($self->_prefix . ':' . $key, $value); $key = $self->_encode_key($key)
or return;
return $self->{memcached}->set($key, $value);
} }
sub _get { sub _get {
my ($self, $key) = @_; my ($self, $key) = @_;
my $value = $self->{memcached}->get($self->_prefix . ':' . $key); $key = $self->_encode_key($key)
or return;
my $value = $self->{memcached}->get($key);
return unless defined $value; return unless defined $value;
# detaint returned values # detaint returned values
...@@ -187,7 +204,9 @@ sub _get { ...@@ -187,7 +204,9 @@ sub _get {
sub _delete { sub _delete {
my ($self, $key) = @_; my ($self, $key) = @_;
return $self->{memcached}->delete($self->_prefix . ':' . $key); $key = $self->_encode_key($key)
or return;
return $self->{memcached}->delete($key);
} }
1; 1;
......
...@@ -113,6 +113,7 @@ sub update { ...@@ -113,6 +113,7 @@ sub update {
$dbh->do('UPDATE products SET defaultmilestone = ? $dbh->do('UPDATE products SET defaultmilestone = ?
WHERE id = ? AND defaultmilestone = ?', WHERE id = ? AND defaultmilestone = ?',
undef, ($self->name, $self->product_id, $changes->{value}->[0])); undef, ($self->name, $self->product_id, $changes->{value}->[0]));
Bugzilla->memcached->clear({ table => 'produles', id => $self->product_id });
} }
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
......
...@@ -35,9 +35,8 @@ use constant AUDIT_UPDATES => 1; ...@@ -35,9 +35,8 @@ use constant AUDIT_UPDATES => 1;
use constant AUDIT_REMOVES => 1; use constant AUDIT_REMOVES => 1;
# When USE_MEMCACHED is true, the class is suitable for serialisation to # When USE_MEMCACHED is true, the class is suitable for serialisation to
# Memcached. This will be flipped to true by default once the majority of # Memcached. See documentation in Bugzilla::Memcached for more information.
# Bugzilla Object have been tested with Memcached. use constant USE_MEMCACHED => 1;
use constant USE_MEMCACHED => 0;
# This allows the JSON-RPC interface to return Bugzilla::Object instances # This allows the JSON-RPC interface to return Bugzilla::Object instances
# as though they were hashes. In the future, this may be modified to return # as though they were hashes. In the future, this may be modified to return
......
...@@ -42,6 +42,9 @@ use constant VALIDATORS => { ...@@ -42,6 +42,9 @@ use constant VALIDATORS => {
use constant UPDATE_COLUMNS => qw(bug_list list_order); use constant UPDATE_COLUMNS => qw(bug_list list_order);
# There's no gain to caching these objects
use constant USE_MEMCACHED => 0;
################### ###################
# DB Manipulation # # DB Manipulation #
################### ###################
......
...@@ -187,6 +187,7 @@ sub rename_field_value { ...@@ -187,6 +187,7 @@ sub rename_field_value {
} }
$dbh->do("UPDATE $table SET query = ? WHERE $id_field = ?", $dbh->do("UPDATE $table SET query = ? WHERE $id_field = ?",
undef, $query, $id); undef, $query, $id);
Bugzilla->memcached->clear({ table => $table, id => $id });
} }
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
......
...@@ -278,6 +278,7 @@ sub update_last_seen_date { ...@@ -278,6 +278,7 @@ sub update_last_seen_date {
# pending changes # pending changes
$dbh->do("UPDATE profiles SET last_seen_date = ? WHERE userid = ?", $dbh->do("UPDATE profiles SET last_seen_date = ? WHERE userid = ?",
undef, $date, $self->id); undef, $date, $self->id);
Bugzilla->memcached->clear({ table => 'profiles', id => $self->id });
} }
} }
......
...@@ -382,6 +382,7 @@ if ($cmdtype eq "dorem") { ...@@ -382,6 +382,7 @@ if ($cmdtype eq "dorem") {
$dbh->do('DELETE FROM namedquery_group_map $dbh->do('DELETE FROM namedquery_group_map
WHERE namedquery_id = ?', WHERE namedquery_id = ?',
undef, $query_id); undef, $query_id);
Bugzilla->memcached->clear({ table => 'namedqueries', id => $query_id });
} }
# Now reset the cached queries # Now reset the cached queries
......
...@@ -222,4 +222,9 @@ $user->derive_regexp_groups(); ...@@ -222,4 +222,9 @@ $user->derive_regexp_groups();
# Commit the transaction # Commit the transaction
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
# It's complex to determine which items now need to be flushed from memcached.
# As user merge is expected to be a rare event, we just flush the entire cache
# when users are merged.
Bugzilla->memcached->clear_all();
print "Done.\n"; print "Done.\n";
...@@ -191,6 +191,7 @@ if ($action eq 'reclassify') { ...@@ -191,6 +191,7 @@ if ($action eq 'reclassify') {
my $sth = $dbh->prepare("UPDATE products SET classification_id = ? my $sth = $dbh->prepare("UPDATE products SET classification_id = ?
WHERE name = ?"); WHERE name = ?");
my @names;
if (defined $cgi->param('add_products')) { if (defined $cgi->param('add_products')) {
check_token_data($token, 'reclassify_classifications'); check_token_data($token, 'reclassify_classifications');
...@@ -198,6 +199,7 @@ if ($action eq 'reclassify') { ...@@ -198,6 +199,7 @@ if ($action eq 'reclassify') {
foreach my $prod ($cgi->param("prodlist")) { foreach my $prod ($cgi->param("prodlist")) {
trick_taint($prod); trick_taint($prod);
$sth->execute($classification->id, $prod); $sth->execute($classification->id, $prod);
push @names, $prod;
} }
} }
delete_token($token); delete_token($token);
...@@ -206,7 +208,8 @@ if ($action eq 'reclassify') { ...@@ -206,7 +208,8 @@ if ($action eq 'reclassify') {
if (defined $cgi->param('myprodlist')) { if (defined $cgi->param('myprodlist')) {
foreach my $prod ($cgi->param("myprodlist")) { foreach my $prod ($cgi->param("myprodlist")) {
trick_taint($prod); trick_taint($prod);
$sth->execute(1,$prod); $sth->execute(1, $prod);
push @names, $prod;
} }
} }
delete_token($token); delete_token($token);
...@@ -216,6 +219,10 @@ if ($action eq 'reclassify') { ...@@ -216,6 +219,10 @@ if ($action eq 'reclassify') {
$vars->{'classification'} = $classification; $vars->{'classification'} = $classification;
$vars->{'token'} = issue_session_token('reclassify_classifications'); $vars->{'token'} = issue_session_token('reclassify_classifications');
foreach my $name (@names) {
Bugzilla->memcached->clear({ table => 'products', name => $name });
}
LoadTemplate($action); LoadTemplate($action);
} }
......
...@@ -650,6 +650,11 @@ if ($action eq 'search') { ...@@ -650,6 +650,11 @@ if ($action eq 'search') {
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
delete_token($token); delete_token($token);
# It's complex to determine which items now need to be flushed from
# memcached. As user deletion is expected to be a rare event, we just
# flush the entire cache when a user is deleted.
Bugzilla->memcached->clear_all();
$vars->{'message'} = 'account_deleted'; $vars->{'message'} = 'account_deleted';
$vars->{'otheruser'}{'login'} = $otherUser->login; $vars->{'otheruser'}{'login'} = $otherUser->login;
$vars->{'restrictablegroups'} = $user->bless_groups(); $vars->{'restrictablegroups'} = $user->bless_groups();
......
...@@ -14,6 +14,7 @@ use Bugzilla; ...@@ -14,6 +14,7 @@ use Bugzilla;
use Bugzilla::Bug; use Bugzilla::Bug;
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::Search; use Bugzilla::Search;
use Bugzilla::Search::Saved;
use Bugzilla::User; use Bugzilla::User;
use Bugzilla::Util; use Bugzilla::Util;
use Bugzilla::Error; use Bugzilla::Error;
...@@ -76,9 +77,11 @@ if ($cgi->param('nukedefaultquery')) { ...@@ -76,9 +77,11 @@ if ($cgi->param('nukedefaultquery')) {
if ($userid) { if ($userid) {
my $token = $cgi->param('token'); my $token = $cgi->param('token');
check_hash_token($token, ['nukedefaultquery']); check_hash_token($token, ['nukedefaultquery']);
$dbh->do("DELETE FROM namedqueries" . my $named_queries = Bugzilla::Search::Saved->match(
" WHERE userid = ? AND name = ?", { userid => $userid, name => DEFAULT_QUERY_NAME });
undef, ($userid, DEFAULT_QUERY_NAME)); if (@$named_queries) {
$named_queries->[0]->remove_from_db();
}
} }
$buffer = ""; $buffer = "";
} }
......
...@@ -73,6 +73,7 @@ else { ...@@ -73,6 +73,7 @@ else {
} }
} }
my $vars = {}; my $vars = {};
my $clear_memcached = 0;
print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_CMDLINE; print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_CMDLINE;
...@@ -149,6 +150,7 @@ if ($cgi->param('createmissinggroupcontrolmapentries')) { ...@@ -149,6 +150,7 @@ if ($cgi->param('createmissinggroupcontrolmapentries')) {
} }
Status('group_control_map_entries_repaired', {counter => $counter}); Status('group_control_map_entries_repaired', {counter => $counter});
$clear_memcached = 1 if $counter;
} }
########################################################################### ###########################################################################
...@@ -175,6 +177,7 @@ if ($cgi->param('repair_creation_date')) { ...@@ -175,6 +177,7 @@ if ($cgi->param('repair_creation_date')) {
$sth_UpdateDate->execute($date, $bugid); $sth_UpdateDate->execute($date, $bugid);
} }
Status('bug_creation_date_fixed', {bug_count => scalar(@$bug_ids)}); Status('bug_creation_date_fixed', {bug_count => scalar(@$bug_ids)});
$clear_memcached = 1 if @$bug_ids;
} }
########################################################################### ###########################################################################
...@@ -191,6 +194,7 @@ if ($cgi->param('repair_everconfirmed')) { ...@@ -191,6 +194,7 @@ if ($cgi->param('repair_everconfirmed')) {
$dbh->do("UPDATE bugs SET everconfirmed = 1 WHERE bug_status IN ($confirmed_open_states)"); $dbh->do("UPDATE bugs SET everconfirmed = 1 WHERE bug_status IN ($confirmed_open_states)");
Status('everconfirmed_end'); Status('everconfirmed_end');
$clear_memcached = 1;
} }
########################################################################### ###########################################################################
...@@ -211,6 +215,7 @@ if ($cgi->param('repair_bugs_fulltext')) { ...@@ -211,6 +215,7 @@ if ($cgi->param('repair_bugs_fulltext')) {
} }
Status('bugs_fulltext_fixed', {bug_count => scalar(@$bug_ids)}); Status('bugs_fulltext_fixed', {bug_count => scalar(@$bug_ids)});
$clear_memcached = 1 if @$bug_ids;
} }
########################################################################### ###########################################################################
...@@ -246,7 +251,10 @@ if ($cgi->param('rescanallBugMail')) { ...@@ -246,7 +251,10 @@ if ($cgi->param('rescanallBugMail')) {
Bugzilla::BugMail::Send($bugid, $vars); Bugzilla::BugMail::Send($bugid, $vars);
} }
Status('send_bugmail_end') if scalar(@$list); if (@$list) {
Status('send_bugmail_end');
Bugzilla->memcached->clear_all();
}
unless (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) { unless (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
$template->process('global/footer.html.tmpl', $vars) $template->process('global/footer.html.tmpl', $vars)
...@@ -280,6 +288,7 @@ if ($cgi->param('remove_invalid_bug_references')) { ...@@ -280,6 +288,7 @@ if ($cgi->param('remove_invalid_bug_references')) {
if (scalar(@$bug_ids)) { if (scalar(@$bug_ids)) {
$dbh->do("DELETE FROM $table WHERE $field IN (" . join(',', @$bug_ids) . ")"); $dbh->do("DELETE FROM $table WHERE $field IN (" . join(',', @$bug_ids) . ")");
$clear_memcached = 1;
} }
} }
...@@ -310,6 +319,7 @@ if ($cgi->param('remove_invalid_attach_references')) { ...@@ -310,6 +319,7 @@ if ($cgi->param('remove_invalid_attach_references')) {
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
Status('attachment_reference_deletion_end'); Status('attachment_reference_deletion_end');
$clear_memcached = 1 if @$attach_ids;
} }
########################################################################### ###########################################################################
...@@ -336,12 +346,17 @@ if ($cgi->param('remove_old_whine_targets')) { ...@@ -336,12 +346,17 @@ if ($cgi->param('remove_old_whine_targets')) {
$dbh->do("DELETE FROM whine_schedules $dbh->do("DELETE FROM whine_schedules
WHERE mailto_type = $type AND mailto IN (" . WHERE mailto_type = $type AND mailto IN (" .
join(',', @$old_ids) . ")"); join(',', @$old_ids) . ")");
$clear_memcached = 1;
} }
} }
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();
Status('whines_obsolete_target_deletion_end'); Status('whines_obsolete_target_deletion_end');
} }
# If any repairs were attempted or made, we need to clear memcached to ensure
# state is consistent.
Bugzilla->memcached->clear_all() if $clear_memcached;
########################################################################### ###########################################################################
# Repair hook # Repair hook
########################################################################### ###########################################################################
...@@ -717,6 +732,7 @@ if (scalar(@invalid_flags)) { ...@@ -717,6 +732,7 @@ if (scalar(@invalid_flags)) {
# Silently delete these flags, with no notification to requesters/setters. # Silently delete these flags, with no notification to requesters/setters.
$dbh->do('DELETE FROM flags WHERE id IN (' . join(',', @flag_ids) .')'); $dbh->do('DELETE FROM flags WHERE id IN (' . join(',', @flag_ids) .')');
Status('flag_deletion_end'); Status('flag_deletion_end');
Bugzilla->memcached->clear_all();
} }
else { else {
foreach my $flag (@$invalid_flags) { foreach my $flag (@$invalid_flags) {
......
...@@ -497,6 +497,7 @@ sub SaveSavedSearches { ...@@ -497,6 +497,7 @@ sub SaveSavedSearches {
$dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?", $dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?",
undef, ($showmybugslink, $user->id)); undef, ($showmybugslink, $user->id));
$user->{'showmybugslink'} = $showmybugslink; $user->{'showmybugslink'} = $showmybugslink;
Bugzilla->memcached->clear({ table => 'profiles', id => $user->id });
} }
......
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