HEX
Server: Apache/2.4.65 (Debian)
System: Linux 88f31f35b0b8 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02) x86_64
User: www-data (33)
PHP: 8.2.29
Disabled: NONE
Upload Files
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;
    }

}