File: /var/www/html/wp-content/plugins/adnkronos/src/Import/ImportMutex.php
<?php
namespace AdnKronos\Import;
use AdnKronos\Psr\Log\LoggerInterface;
/**
* MySQL advisory lock used to prevent concurrent import runs.
*
* Uses GET_LOCK / RELEASE_LOCK instead of a transient so that:
* - The lock is acquired and checked atomically at the DB level.
* - The lock is automatically released if the PHP process dies
* (MySQL drops it when the connection closes).
* - Cron spawn and admin "Importa Ora" button, which run on separate
* DB connections, correctly block each other.
*
* acquire() uses timeout=0 (no waiting): if the lock is already held
* the caller gets false immediately and can skip the import.
*/
class ImportMutex {
const LOCK_NAME = 'adnk_import';
/** @var LoggerInterface */
private $logger;
/** @var bool */
private $acquired = false;
public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
/**
* Tries to acquire the lock without waiting.
*
* @return bool True if the lock was acquired, false if already held by another connection.
*/
public function acquire() {
global $wpdb;
$result = $wpdb->get_var(
$wpdb->prepare('SELECT GET_LOCK(%s, 0)', self::LOCK_NAME)
);
$this->acquired = ($result === '1');
if (!$this->acquired) {
$this->logger->info('ImportMutex: lock already held by another process');
}
return $this->acquired;
}
/**
* Releases the lock. No-op if this instance never acquired it.
*/
public function release() {
if (!$this->acquired) {
return;
}
global $wpdb;
$wpdb->get_var(
$wpdb->prepare('SELECT RELEASE_LOCK(%s)', self::LOCK_NAME)
);
$this->acquired = false;
$this->logger->info('ImportMutex: lock released');
}
/**
* @return bool
*/
public function isAcquired() {
return $this->acquired;
}
}