Jake Vanderwerf
2026-05-12 457c329237f97069063e641b10f384a52d584f21
inc/managers/queue/Locker.php
@@ -1,5 +1,7 @@
<?php
namespace JVBase\managers\queue;
use wpdb;
if (!defined('ABSPATH')) {
   exit;
}
@@ -7,59 +9,50 @@
class Locker
{
   private string $lockKey;
   private int $ttl;
   private int $timeout;
   protected wpdb $wpdb;
   private ?string $token = null;
   public function __construct(string $key = 'queue_processor', int $ttl = 300)
   public function __construct(string $key = 'queue', int $timeout = 0)
   {
      $this->lockKey = BASE . '_lock_' . $key;
      $this->ttl = $ttl;
   }
   public function acquire(): bool
   {
      // Generate unique token for this process
      $this->token = uniqid(gethostname() . '_', true);
      // SET NX with TTL - atomic "set if not exists"
      $result = wp_cache_add($this->lockKey, $this->token, 'locks', $this->ttl);
      return $result === true;
   }
   public function release(): void
   {
      if (!$this->token) {
         return;
      }
      // Only release if we own the lock
      $current = wp_cache_get($this->lockKey, 'locks');
      if ($current === $this->token) {
         wp_cache_delete($this->lockKey, 'locks');
      }
      $this->token = null;
   }
   public function isLocked(): bool
   {
      return wp_cache_get($this->lockKey, 'locks') !== false;
      $this->lockKey = BASE . $key . '_lock';
      $this->timeout = $timeout;
      global $wpdb;
      $this->wpdb = $wpdb;
   }
   /**
    * Execute callback with lock, auto-release after
    */
   public function withLock(callable $callback): mixed
   public function withLock(callable $callback): void
   {
      if (!$this->acquire()) {
         return null;
      $acquired = $this->wpdb->get_var(
         $this->wpdb->prepare(
            'SELECT GET_LOCK(%s, %d)',
            $this->lockKey,
            $this->timeout
         )
      );
      if ((int) $acquired !== 1) {
         // Lock already held — just exit quietly
         return;
      }
      try {
         return $callback();
         $callback();
      } finally {
         $this->release();
         $this->unlock();
      }
   }
   public function unlock():void
   {
      $this->wpdb->get_var(
         $this->wpdb->prepare(
            'SELECT RELEASE_LOCK(%s)',
            $this->lockKey
         )
      );
   }
}