annotate core/lib/Drupal/Core/Lock/LockBackendInterface.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Lock;
Chris@0 4
Chris@0 5 /**
Chris@0 6 * @defgroup lock Locking mechanisms
Chris@0 7 * @{
Chris@0 8 * Functions to coordinate long operations across requests.
Chris@0 9 *
Chris@0 10 * In most environments, multiple Drupal page requests (a.k.a. threads or
Chris@0 11 * processes) will execute in parallel. This leads to potential conflicts or
Chris@0 12 * race conditions when two requests execute the same code at the same time. For
Chris@0 13 * instance, some implementations of hook_cron() implicitly assume they are
Chris@0 14 * running only once, rather than having multiple calls in parallel. To prevent
Chris@0 15 * problems with such code, the cron system uses a locking process to ensure
Chris@0 16 * that cron is not started again if it is already running.
Chris@0 17 *
Chris@0 18 * To avoid these types of conflicts, Drupal has a cooperative, advisory lock
Chris@0 19 * system. Any long-running operation that could potentially be attempted in
Chris@0 20 * parallel by multiple requests should try to acquire a lock before
Chris@0 21 * proceeding. By obtaining a lock, one request notifies any other requests that
Chris@0 22 * a specific operation is in progress which must not be executed in parallel.
Chris@0 23 *
Chris@0 24 * To use this API, pick a unique name for the lock. A sensible choice is the
Chris@0 25 * name of the function performing the operation. Here is a simple example:
Chris@0 26 * @code
Chris@0 27 * function mymodule_long_operation() {
Chris@0 28 * $lock = \Drupal::lock();
Chris@0 29 * if ($lock->acquire('mymodule_long_operation')) {
Chris@0 30 * // Do the long operation here.
Chris@0 31 * // ...
Chris@0 32 * $lock->release('mymodule_long_operation');
Chris@0 33 * }
Chris@0 34 * }
Chris@0 35 * @endcode
Chris@0 36 *
Chris@0 37 * If a function acquires a lock it should always release it when the operation
Chris@0 38 * is complete by calling $lock->release(), as in the example.
Chris@0 39 *
Chris@0 40 * A function that has acquired a lock may attempt to renew a lock (extend the
Chris@0 41 * duration of the lock) by calling $lock->acquire() again during the operation.
Chris@0 42 * Failure to renew a lock is indicative that another request has acquired the
Chris@0 43 * lock, and that the current operation may need to be aborted.
Chris@0 44 *
Chris@0 45 * If a function fails to acquire a lock it may either immediately return, or
Chris@0 46 * it may call $lock->wait() if the rest of the current page request requires
Chris@0 47 * that the operation in question be complete. After $lock->wait() returns, the
Chris@0 48 * function may again attempt to acquire the lock, or may simply allow the page
Chris@0 49 * request to proceed on the assumption that a parallel request completed the
Chris@0 50 * operation.
Chris@0 51 *
Chris@0 52 * $lock->acquire() and $lock->wait() will automatically break (delete) a lock
Chris@0 53 * whose duration has exceeded the timeout specified when it was acquired.
Chris@0 54 *
Chris@0 55 * The following limitations in this implementation should be carefully noted:
Chris@0 56 * - Time: Timestamps are derived from the local system clock of the environment
Chris@0 57 * the code is executing in. The orderly progression of time from this
Chris@0 58 * viewpoint can be disrupted by external events such as NTP synchronization
Chris@0 59 * and operator intervention. Where multiple web servers are involved in
Chris@0 60 * serving the site, they will have their own independent clocks, introducing
Chris@0 61 * another source of error in the time keeping process. Timeout values applied
Chris@0 62 * to locks must therefore be considered approximate, and should not be relied
Chris@0 63 * upon.
Chris@0 64 * - Uniqueness: Uniqueness of lock names is not enforced. The impact of the
Chris@0 65 * use of a common lock name will depend on what processes and resources the
Chris@0 66 * lock is being used to manage.
Chris@0 67 * - Sharing: There is limited support for resources shared across sites.
Chris@0 68 * The locks are stored as rows in the semaphore table and, as such, they
Chris@0 69 * have the same visibility as the table. If resources managed by a lock are
Chris@0 70 * shared across sites then the semaphore table must be shared across sites
Chris@0 71 * as well. This is a binary situation: either all resources are shared and
Chris@0 72 * the semaphore table is shared or no resources are shared and the semaphore
Chris@0 73 * table is not shared. Mixed mode operation is not supported.
Chris@0 74 *
Chris@0 75 * @} End of "defgroup lock".
Chris@0 76 */
Chris@0 77
Chris@0 78 /**
Chris@0 79 * Lock backend interface.
Chris@0 80 *
Chris@0 81 * @ingroup lock
Chris@0 82 */
Chris@0 83 interface LockBackendInterface {
Chris@0 84
Chris@0 85 /**
Chris@0 86 * Acquires a lock.
Chris@0 87 *
Chris@0 88 * @param string $name
Chris@0 89 * Lock name. Limit of name's length is 255 characters.
Chris@0 90 * @param float $timeout
Chris@0 91 * (optional) Lock lifetime in seconds. Defaults to 30.0.
Chris@0 92 *
Chris@0 93 * @return bool
Chris@0 94 */
Chris@0 95 public function acquire($name, $timeout = 30.0);
Chris@0 96
Chris@0 97 /**
Chris@0 98 * Checks if a lock is available for acquiring.
Chris@0 99 *
Chris@0 100 * @param string $name
Chris@0 101 * Lock to acquire.
Chris@0 102 *
Chris@0 103 * @return bool
Chris@0 104 */
Chris@0 105 public function lockMayBeAvailable($name);
Chris@0 106
Chris@0 107 /**
Chris@0 108 * Waits a short amount of time before a second lock acquire attempt.
Chris@0 109 *
Chris@0 110 * While this method is subject to have a generic implementation in abstract
Chris@0 111 * backend implementation, some backends may provide non blocking or less I/O
Chris@0 112 * intensive wait mechanism: this is why this method remains on the backend
Chris@0 113 * interface.
Chris@0 114 *
Chris@0 115 * @param string $name
Chris@0 116 * Lock name currently being locked.
Chris@0 117 * @param int $delay
Chris@0 118 * Seconds to wait for. Defaults to 30.
Chris@0 119 *
Chris@0 120 * @return bool
Chris@0 121 * TRUE if the lock holds, FALSE if it may be available. You still need to
Chris@0 122 * acquire the lock manually and it may fail again.
Chris@0 123 */
Chris@0 124 public function wait($name, $delay = 30);
Chris@0 125
Chris@0 126 /**
Chris@0 127 * Releases the given lock.
Chris@0 128 *
Chris@0 129 * @param string $name
Chris@0 130 */
Chris@0 131 public function release($name);
Chris@0 132
Chris@0 133 /**
Chris@0 134 * Releases all locks for the given lock token identifier.
Chris@0 135 *
Chris@0 136 * @param string $lockId
Chris@0 137 * (optional) If none given, remove all locks from the current page.
Chris@0 138 * Defaults to NULL.
Chris@0 139 */
Chris@0 140 public function releaseAll($lockId = NULL);
Chris@0 141
Chris@0 142 /**
Chris@0 143 * Gets the unique page token for locks.
Chris@0 144 *
Chris@0 145 * Locks will be wiped out at the end of each page request on a token basis.
Chris@0 146 *
Chris@0 147 * @return string
Chris@0 148 */
Chris@0 149 public function getLockId();
Chris@0 150
Chris@0 151 }