mirror of
https://github.com/Mibew/mibew.git
synced 2025-01-31 13:24:41 +03:00
Encapsulate locks mechanics in "ProcessLock" class
This commit is contained in:
parent
22699f1ed5
commit
b3c9a02660
95
src/mibew/libs/classes/Mibew/ProcessLock.php
Normal file
95
src/mibew/libs/classes/Mibew/ProcessLock.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is a part of Mibew Messenger.
|
||||
*
|
||||
* Copyright 2005-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Mibew;
|
||||
|
||||
use Mibew\Settings;
|
||||
|
||||
/**
|
||||
* Watch the process is ran only once.
|
||||
*/
|
||||
class ProcessLock
|
||||
{
|
||||
/**
|
||||
* Name of the lock.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Time to live of the lock.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $ttl;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $name Name of the lock.
|
||||
* @param int $ttl Time after the lock will be automatically released.
|
||||
*/
|
||||
public function __construct($name, $ttl = 300)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->ttl = $ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to get the lock.
|
||||
*
|
||||
* @return boolean True if the lock has been got and false otherwise.
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// Check if we can get the lock
|
||||
$lock_timestamp = (int)Settings::get($this->getInternalName(), 0);
|
||||
$is_lock_free = !$lock_timestamp
|
||||
// Lock cannot be got for more than ttl.
|
||||
|| (time() - $lock_timestamp) > $this->ttl;
|
||||
|
||||
if (!$is_lock_free) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the lock
|
||||
Settings::set($this->getInternalName(), time());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the lock
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
Settings::set($this->getInternalName(), '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds internal name of the lock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getInternalName()
|
||||
{
|
||||
return '_' . $this->name . '_lock_time';
|
||||
}
|
||||
}
|
@ -382,18 +382,10 @@ class Thread
|
||||
return;
|
||||
}
|
||||
|
||||
// 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());
|
||||
// We need to run only one instance of cleaning process.
|
||||
$lock = new ProcessLock('threads_close_old');
|
||||
|
||||
if ($lock->get()) {
|
||||
$query = "SELECT * FROM {thread} "
|
||||
. "WHERE istate <> :state_closed "
|
||||
. "AND istate <> :state_left "
|
||||
@ -454,7 +446,7 @@ class Thread
|
||||
}
|
||||
|
||||
// Release the lock
|
||||
Settings::set('_threads_close_old_lock_time', '0');
|
||||
$lock->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user