Commit | Line | Data |
---|---|---|
10760fa1 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
41498ac5 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
10760fa1 | 5 | | | |
41498ac5 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
10760fa1 TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | namespace Civi\Core\Lock; | |
12 | ||
13 | use Civi\Core\Resolver; | |
14 | ||
15 | /** | |
16 | * Class LockManager | |
17 | * @package Civi\Core\Lock | |
18 | * | |
19 | * The lock-manager allows one to define the lock policy -- i.e. given a | |
20 | * specific lock, how does one acquire the lock? | |
21 | */ | |
22 | class LockManager { | |
23 | ||
c64f69d9 | 24 | private $rules = []; |
10760fa1 TO |
25 | |
26 | /** | |
27 | * @param string $name | |
28 | * Symbolic name for the lock. Names generally look like | |
29 | * "worker.mailing.EmailProcessor" ("{category}.{component}.{AdhocName}"). | |
30 | * | |
31 | * Categories: worker|data|cache|... | |
32 | * Component: core|mailing|member|contribute|... | |
33 | * @return LockInterface | |
34 | * @throws \CRM_Core_Exception | |
35 | */ | |
36 | public function create($name) { | |
37 | $factory = $this->getFactory($name); | |
38 | if ($factory) { | |
39 | /** @var LockInterface $lock */ | |
c64f69d9 | 40 | $lock = call_user_func_array($factory, [$name]); |
10760fa1 TO |
41 | return $lock; |
42 | } | |
43 | else { | |
44 | throw new \CRM_Core_Exception("Lock \"$name\" does not match any rules. Use register() to add more rules."); | |
45 | } | |
46 | } | |
47 | ||
48 | /** | |
49 | * Create and attempt to acquire a lock. | |
50 | * | |
51 | * Note: Be sure to check $lock->isAcquired() to determine whether | |
52 | * acquisition was successful. | |
53 | * | |
54 | * @param string $name | |
55 | * Symbolic name for the lock. Names generally look like | |
56 | * "worker.mailing.EmailProcessor" ("{category}.{component}.{AdhocName}"). | |
57 | * | |
58 | * Categories: worker|data|cache|... | |
59 | * Component: core|mailing|member|contribute|... | |
e97c66ff | 60 | * @param int|null $timeout |
10760fa1 TO |
61 | * The number of seconds to wait to get the lock. |
62 | * For a default value, use NULL. | |
63 | * @return LockInterface | |
64 | * @throws \CRM_Core_Exception | |
65 | */ | |
66 | public function acquire($name, $timeout = NULL) { | |
67 | $lock = $this->create($name); | |
68 | $lock->acquire($timeout); | |
69 | return $lock; | |
70 | } | |
71 | ||
72 | /** | |
73 | * @param string $name | |
74 | * Symbolic name for the lock. | |
75 | * @return callable|NULL | |
76 | */ | |
77 | public function getFactory($name) { | |
78 | foreach ($this->rules as $rule) { | |
79 | if (preg_match($rule['pattern'], $name)) { | |
80 | return Resolver::singleton()->get($rule['factory']); | |
81 | } | |
82 | } | |
83 | return NULL; | |
84 | } | |
85 | ||
86 | /** | |
87 | * Register the lock-factory to use for specific lock-names. | |
88 | * | |
89 | * @param string $pattern | |
90 | * A regex to match against the lock name. | |
91 | * @param string|array $factory | |
92 | * A callback. The callback should accept a $name parameter. | |
93 | * Callbacks will be located using the resolver. | |
4b350175 | 94 | * @return LockManager |
10760fa1 TO |
95 | * @see Resolver |
96 | */ | |
97 | public function register($pattern, $factory) { | |
c64f69d9 | 98 | $this->rules[] = [ |
10760fa1 TO |
99 | 'pattern' => $pattern, |
100 | 'factory' => $factory, | |
c64f69d9 | 101 | ]; |
10760fa1 TO |
102 | return $this; |
103 | } | |
104 | ||
105 | } |