Jake Vanderwerf
2026-01-20 7a9054bb3f033c98067b3196378311dae54c5fbf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
namespace JVBase\managers\queue;
if (!defined('ABSPATH')) {
    exit;
}
 
class Locker
{
    private string $lockKey;
    private int $ttl;
    private ?string $token = null;
 
    public function __construct(string $key = 'queue_processor', int $ttl = 300)
    {
        $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;
    }
 
    /**
     * Execute callback with lock, auto-release after
     */
    public function withLock(callable $callback): mixed
    {
        if (!$this->acquire()) {
            return null;
        }
 
        try {
            return $callback();
        } finally {
            $this->release();
        }
    }
}