Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/util/PhabricatorGlobalLock.php
| Show All 25 Lines | |||||
| * @task construct Constructing Locks | * @task construct Constructing Locks | ||||
| * @task impl Implementation | * @task impl Implementation | ||||
| */ | */ | ||||
| final class PhabricatorGlobalLock extends PhutilLock { | final class PhabricatorGlobalLock extends PhutilLock { | ||||
| private $parameters; | private $parameters; | ||||
| private $conn; | private $conn; | ||||
| private $isExternalConnection = false; | private $isExternalConnection = false; | ||||
| private $log; | |||||
| private $disableLogging; | |||||
| private static $pool = array(); | private static $pool = array(); | ||||
| /* -( Constructing Locks )------------------------------------------------- */ | /* -( Constructing Locks )------------------------------------------------- */ | ||||
| public static function newLock($name, $parameters = array()) { | public static function newLock($name, $parameters = array()) { | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | /* -( Constructing Locks )------------------------------------------------- */ | ||||
| * @return this | * @return this | ||||
| */ | */ | ||||
| public function useSpecificConnection(AphrontDatabaseConnection $conn) { | public function useSpecificConnection(AphrontDatabaseConnection $conn) { | ||||
| $this->conn = $conn; | $this->conn = $conn; | ||||
| $this->isExternalConnection = true; | $this->isExternalConnection = true; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function setDisableLogging($disable) { | |||||
| $this->disableLogging = $disable; | |||||
| return $this; | |||||
| } | |||||
| /* -( Implementation )----------------------------------------------------- */ | /* -( Implementation )----------------------------------------------------- */ | ||||
| protected function doLock($wait) { | protected function doLock($wait) { | ||||
| $conn = $this->conn; | $conn = $this->conn; | ||||
| if (!$conn) { | if (!$conn) { | ||||
| // Try to reuse a connection from the connection pool. | // Try to reuse a connection from the connection pool. | ||||
| Show All 32 Lines | protected function doLock($wait) { | ||||
| $ok = head($result); | $ok = head($result); | ||||
| if (!$ok) { | if (!$ok) { | ||||
| throw new PhutilLockException($lock_name); | throw new PhutilLockException($lock_name); | ||||
| } | } | ||||
| $conn->rememberLock($lock_name); | $conn->rememberLock($lock_name); | ||||
| $this->conn = $conn; | $this->conn = $conn; | ||||
| if ($this->shouldLogLock()) { | |||||
| global $argv; | |||||
| $lock_context = array( | |||||
| 'pid' => getmypid(), | |||||
| 'host' => php_uname('n'), | |||||
| 'argv' => $argv, | |||||
| ); | |||||
| $log = id(new PhabricatorDaemonLockLog()) | |||||
| ->setLockName($lock_name) | |||||
| ->setLockParameters($this->parameters) | |||||
| ->setLockContext($lock_context) | |||||
| ->save(); | |||||
| $this->log = $log; | |||||
| } | |||||
| } | } | ||||
| protected function doUnlock() { | protected function doUnlock() { | ||||
| $lock_name = $this->getName(); | $lock_name = $this->getName(); | ||||
| $conn = $this->conn; | $conn = $this->conn; | ||||
| try { | try { | ||||
| Show All 16 Lines | protected function doUnlock() { | ||||
| $this->conn = null; | $this->conn = null; | ||||
| $this->isExternalConnection = false; | $this->isExternalConnection = false; | ||||
| if (!$this->isExternalConnection) { | if (!$this->isExternalConnection) { | ||||
| $conn->close(); | $conn->close(); | ||||
| self::$pool[] = $conn; | self::$pool[] = $conn; | ||||
| } | } | ||||
| if ($this->log) { | |||||
| $log = $this->log; | |||||
| $this->log = null; | |||||
| $conn = $log->establishConnection('w'); | |||||
| queryfx( | |||||
| $conn, | |||||
| 'UPDATE %T SET lockReleased = UNIX_TIMESTAMP() WHERE id = %d', | |||||
| $log->getTableName(), | |||||
| $log->getID()); | |||||
| } | |||||
| } | |||||
| private function shouldLogLock() { | |||||
| if ($this->disableLogging) { | |||||
| return false; | |||||
| } | |||||
| $policy = id(new PhabricatorDaemonLockLogGarbageCollector()) | |||||
| ->getRetentionPolicy(); | |||||
| if (!$policy) { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | } | ||||
| } | } | ||||