Почему мой класс мьютекса иногда не удаляет файл мьютекса?

У меня есть плагин WordPress, который я создал, который просто экспортирует заказы в стороннюю систему. Чтобы предотвратить возможные проблемы, связанные с тем, что плагин запускается более одного раза одновременно, я использую следующий код Mutex, однако иногда файл mutex не удаляется, что останавливает работу моего плагина, пока я не удалил файл вручную.

<?php

class System_Mutex
{
var $lockName = "";
var $fileName = null;
var $file = null;

public function __construct($lockName) {
$this->lockName = preg_replace('/[^a-z0-9]/', '', $lockName);
$this->getFileName();
}

public function __destruct() {
$this->releaseLock();
}

public function isLocked() {
return ! flock($this->file, LOCK_SH | LOCK_NB);
}

public function getLock() {
return flock($this->file, LOCK_EX | LOCK_NB);
}

public function releaseLock() {
if ( ! is_resource($this->file) ) return true;
$success = flock($this->file, LOCK_UN);
fclose($this->file);
return $success;
}

public function getFileName() {
$this->fileName = dirname(__FILE__) . "/../Locks/" . $this->lockName . ".lock";

if ( ! $this->file = fopen($this->fileName, "c") ) {
throw new Exception("Cannot create temporary lock file.");
}
}
}

Сам Mutex используется так:

try {
$mutex_id = "ef_stock_sync";
$mutex = new System_Mutex($mutex_id);
//mutex is locked- exit process
if ( $mutex->isLocked() || ! $mutex->getLock() ) {
//
return;
}
} catch ( Exception $e ) {
//
return;
}
$this->_syncStock();
$mutex->releaseLock();

Есть идеи, почему это происходит? Я думал, что деструктор класса будет гарантировать, что он будет удален, даже если код должен был остановиться на полпути?

0

Решение

Слишком широкий, чтобы ответить с уверенностью, и блок, скорее всего, срабатывает из вашего кода плагина. Тем не менее, у вас есть логическая ошибка в вашем System_Mutex учебный класс.

Вы приобретаете эксклюзивный замок в getLock(), но isLocked() пытается получить общую блокировку в качестве проверки. Вы не должны делать это по двум причинам:

  1. Общая блокировка может удерживаться несколькими процессами одновременно (отсюда и ее имя).
  2. Совместная блокировка не предотвращается исключительной блокировкой, полученной тем же процессом.

Я не уверен, что вы используете isLocked() для, но из-за вышеупомянутых 2 правил, независимо от цели, вы можете получить ложные срабатывания. Что я могу сказать вам это:

  • Не смешивайте типы блокировки.
  • Будьте осторожны с проверкой блокировки, потому что это делает приобрести замок самостоятельно.
  • В этом конкретном случае используйте только LOCK_EX,

А также это: https://bugs.php.net/bug.php?id=53769

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]