Prevent race condition in old threads closing

This commit is contained in:
Dmitriy Simushev 2014-10-29 15:12:05 +00:00
parent b5020645be
commit 96c9bf2a93

View File

@ -373,15 +373,26 @@ class Thread
} }
/** /**
* Close all old threads that were not closed by some reasons * Close all old threads that were not closed by some reasons.
*/ */
public static function closeOldThreads() public static function closeOldThreads()
{ {
if (Settings::get('thread_lifetime') == 0) { if (Settings::get('thread_lifetime') == 0) {
// Threads live forever.
return; return;
} }
$db = Database::getInstance(); // We need to run only one instance of cleaning process. Use a lock with
// last run timestamp.
$lock_timestamp = (int)Settings::get('_threads_close_old_lock_time', 0);
$is_lock_free = !$lock_timestamp
// Lock cannot be got for more than 5 minutes. If such situation
// take place we have a deadlock.
|| (time() - $lock_timestamp) > 5 * 60;
if ($is_lock_free) {
// Get the lock
Settings::set('_threads_close_old_lock_time', time());
$query = "UPDATE {thread} SET " $query = "UPDATE {thread} SET "
. "lrevision = :next_revision, " . "lrevision = :next_revision, "
@ -395,8 +406,8 @@ class Thread
// Check pings // Check pings
. "AND ( " . "AND ( "
. "( " . "( "
// Both user and operator have no connection problems. // Both user and operator have no connection
// Check all pings. // problems. Check all pings.
. "lastpingagent <> 0 " . "lastpingagent <> 0 "
. "AND lastpinguser <> 0 " . "AND lastpinguser <> 0 "
. "AND ABS(:now - lastpinguser) > :thread_lifetime " . "AND ABS(:now - lastpinguser) > :thread_lifetime "
@ -421,7 +432,8 @@ class Thread
. ") " . ") "
. ")"; . ")";
$db->query( // Perform the cleaning
Database::getInstance()->query(
$query, $query,
array( array(
':next_revision' => self::nextRevision(), ':next_revision' => self::nextRevision(),
@ -431,6 +443,10 @@ class Thread
':thread_lifetime' => Settings::get('thread_lifetime'), ':thread_lifetime' => Settings::get('thread_lifetime'),
) )
); );
// Release the lock
Settings::set('_threads_close_old_lock_time', '0');
}
} }
/** /**