Committer: ailyin
LJSUP-13513 (implement additional locks to prevent dataloss in moveucluster)U trunk/cgi-bin/LJ/Worker/UserManage/UserClusterPreMove.pm
Modified: trunk/cgi-bin/LJ/Worker/UserManage/UserClusterPreMove.pm =================================================================== --- trunk/cgi-bin/LJ/Worker/UserManage/UserClusterPreMove.pm 2012-09-03 14:19:45 UTC (rev 12604) +++ trunk/cgi-bin/LJ/Worker/UserManage/UserClusterPreMove.pm 2012-09-03 15:56:34 UTC (rev 12605) @@ -21,17 +21,29 @@ my $u = LJ::want_user($userid) || die "no such user"; + my $dbh = LJ::get_db_writer(); + unless ( LJ::get_lock( $dbh, 'global', "moveucluster:$userid" ) ) { + die "couldn't get a DB lock for checking the readonly cap\n"; + } + + my ($caps) = $dbh->selectrow_array( 'SELECT caps FROM user WHERE userid=?', + undef, $userid ); + my $capclass = LJ::UserManage::READONLY_CAP_CLASS; - if ($u->in_class($capclass)) { + my $capbit = LJ::class_bit($capclass); + + if ( $caps & ( 1 << $capbit ) ) { __PACKAGE__->debug_msg($u->user . ' is already being moved; skipping'); + LJ::release_lock( $dbh, 'global', "moveucluster:$userid" ); return $job->completed; } # we are deliberately not doing the "add_to_class" thing there so that # "caps changed" hooks are not processed. - my $capbit = LJ::class_bit($capclass); LJ::update_user($u, { 'caps' => $u->caps | (1 << $capbit) }); + LJ::release_lock( $dbh, 'global', "moveucluster:$userid" ); + my $dbh = LJ::get_db_writer(); die 'cannot get global cluster writer' unless $dbh;