* @defgroup LockManager Lock management
* @ingroup FileBackend
*/
+use Psr\Log\LoggerInterface;
+use Wikimedia\WaitConditionLoop;
/**
* Resource locking handling.
*
* Locks on resource keys can either be shared or exclusive.
*
- * Implementations must keep track of what is locked by this proccess
+ * Implementations must keep track of what is locked by this process
* in-memory and support nested locking calls (using reference counting).
* At least LOCK_UW and LOCK_EX must be implemented. LOCK_SH can be a no-op.
* Locks should either be non-blocking or have low wait timeouts.
* @since 1.19
*/
abstract class LockManager {
+ /** @var LoggerInterface */
+ protected $logger;
+
/** @var array Mapping of lock types to the type actually used */
protected $lockTypeMap = [
self::LOCK_SH => self::LOCK_SH,
protected $domain; // string; domain (usually wiki ID)
protected $lockTTL; // integer; maximum time locks can be held
+ /** @var string Random 32-char hex number */
+ protected $session;
+
/** Lock types; stronger locks have higher values */
const LOCK_SH = 1; // shared lock (for reads)
const LOCK_UW = 2; // shared lock (for reads used to write elsewhere)
const LOCK_EX = 3; // exclusive lock (for writes)
+ /** @var int Max expected lock expiry in any context */
+ const MAX_LOCK_TTL = 7200; // 2 hours
+
/**
* Construct a new instance from configuration
*
$met = ini_get( 'max_execution_time' ); // this is 0 in CLI mode
$this->lockTTL = max( 5 * 60, 2 * (int)$met );
}
+
+ // Upper bound on how long to keep lock structures around. This is useful when setting
+ // TTLs, as the "lockTTL" value may vary based on CLI mode and app server group. This is
+ // a "safe" value that can be used to avoid clobbering other locks that use high TTLs.
+ $this->lockTTL = min( $this->lockTTL, self::MAX_LOCK_TTL );
+
+ $random = [];
+ for ( $i = 1; $i <= 5; ++$i ) {
+ $random[] = mt_rand( 0, 0xFFFFFFF );
+ }
+ $this->session = md5( implode( '-', $random ) );
+
+ $this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
}
/**
/**
* Get the base 36 SHA-1 of a string, padded to 31 digits.
* Before hashing, the path will be prefixed with the domain ID.
- * This should be used interally for lock key or file names.
+ * This should be used internally for lock key or file names.
*
* @param string $path
* @return string
/**
* Get the base 16 SHA-1 of a string, padded to 31 digits.
* Before hashing, the path will be prefixed with the domain ID.
- * This should be used interally for lock key or file names.
+ * This should be used internally for lock key or file names.
*
* @param string $path
* @return string