PluginProbe
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution / trunk
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution vtrunk
2.0.1 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.9.0 2.0.0
solid-performance / src / Performance / Lock / Lock.php

Lock.php in Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution trunk, at src/Performance/Lock/Lock.php

121 lines 2.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A lock decorator to store a lock in the underlying driver.
4 *
5 * @package SolidWP\Performance
6 */
7
8 declare( strict_types=1 );
9
10 namespace SolidWP\Performance\Lock;
11
12 use SolidWP\Performance\Lock\Contracts\Blockable_Lock;
13 use SolidWP\Performance\Lock\Exceptions\LockTimeoutException;
14
15 /**
16 * A lock decorator to store a lock in the underlying driver.
17 *
18 * @package SolidWP\Performance
19 */
20 final class Lock implements Blockable_Lock {
21
22 /**
23 * @var Contracts\Lock
24 */
25 private Contracts\Lock $driver;
26
27 /**
28 * The time in milliseconds to wait in-between retrying blocking locks.
29 *
30 * @var int
31 */
32 private int $retry_delay;
33
34 /**
35 * @param Contracts\Lock $driver The lock driver.
36 * @param int $retry_delay The time in milliseconds to wait in-between retrying blocking locks.
37 */
38 public function __construct( Contracts\Lock $driver, int $retry_delay = 250 ) {
39 $this->driver = $driver;
40 $this->retry_delay = $retry_delay;
41 }
42
43 /**
44 * Attempt to acquire a lock.
45 *
46 * @return bool
47 */
48 public function acquire(): bool {
49 return $this->driver->acquire();
50 }
51
52 /**
53 * Determine if this lock is already acquired.
54 *
55 * @return bool
56 */
57 public function is_acquired(): bool {
58 return $this->driver->is_acquired();
59 }
60
61 /**
62 * Attempt to acquire the lock for the given number of seconds.
63 *
64 * @param int $seconds How long to wait to acquire the lock before giving up.
65 *
66 * @throws LockTimeoutException If we are unable to acquire the lock within the given seconds.
67 *
68 * @return bool
69 */
70 public function block( int $seconds ): bool {
71 // Convert milliseconds to microseconds.
72 $sleep = $this->retry_delay * 1000;
73 // Start time in microseconds.
74 $start = (int) ( microtime( true ) * 1_000_000 );
75 // Convert the wait time to microseconds.
76 $microseconds_to_wait = $seconds * 1_000_000;
77
78 while ( ! $this->acquire() ) {
79 $now = (int) ( microtime( true ) * 1_000_000 );
80
81 // Elapsed time in microseconds.
82 $elapsed = $now - $start;
83
84 if ( $elapsed >= $microseconds_to_wait ) {
85 throw new LockTimeoutException();
86 }
87
88 usleep( $sleep );
89 }
90
91 return true;
92 }
93
94 /**
95 * Get the original owner of the lock.
96 *
97 * @return string
98 */
99 public function owner(): string {
100 return $this->driver->owner();
101 }
102
103 /**
104 * Release the lock, if the original owner matches the current one.
105 *
106 * @return bool
107 */
108 public function release(): bool {
109 return $this->driver->release();
110 }
111
112 /**
113 * Force release the lock, regardless of who owns it.
114 *
115 * @return bool
116 */
117 public function force_release(): bool {
118 return $this->driver->force_release();
119 }
120 }
121