/** * Get a hash of a file's contents, either by retrieving a previously- * computed hash from the cache, or by computing a hash from the file. * * @private * @param string $filePath Full path to the file. * @param string $algo Name of selected hashing algorithm. * @return string|bool Hash of file contents, or false if the file could not be read. */ public function getFileContentsHashInternal($filePath, $algo = 'md4') { $mtime = filemtime($filePath); if ($mtime === false) { return false; } $cacheKey = $this->cache->makeGlobalKey(__CLASS__, $filePath, $mtime, $algo); $hash = $this->cache->get($cacheKey); if ($hash) { return $hash; } $contents = file_get_contents($filePath); if ($contents === false) { return false; } $hash = hash($algo, $contents); $this->cache->set($cacheKey, $hash, 60 * 60 * 24); // 24h return $hash; }
/** * Wait for a given slave to catch up to the master pos stored in $this * @param int $index Server index * @param bool $open Check the server even if a new connection has to be made * @param int $timeout Max seconds to wait; default is mWaitTimeout * @return bool */ protected function doWait($index, $open = false, $timeout = null) { $close = false; // close the connection afterwards // Check if we already know that the DB has reached this point $server = $this->getServerName($index); $key = $this->srvCache->makeGlobalKey(__CLASS__, 'last-known-pos', $server); /** @var DBMasterPos $knownReachedPos */ $knownReachedPos = $this->srvCache->get($key); if ($knownReachedPos && $knownReachedPos->hasReached($this->mWaitForPos)) { wfDebugLog('replication', __METHOD__ . ": slave {$server} known to be caught up (pos >= {$knownReachedPos}).\n"); return true; } // Find a connection to wait on, creating one if needed and allowed $conn = $this->getAnyOpenConnection($index); if (!$conn) { if (!$open) { wfDebugLog('replication', __METHOD__ . ": no connection open for {$server}\n"); return false; } else { $conn = $this->openConnection($index, ''); if (!$conn) { wfDebugLog('replication', __METHOD__ . ": failed to connect to {$server}\n"); return false; } // Avoid connection spam in waitForAll() when connections // are made just for the sake of doing this lag check. $close = true; } } wfDebugLog('replication', __METHOD__ . ": Waiting for slave {$server} to catch up...\n"); $timeout = $timeout ?: $this->mWaitTimeout; $result = $conn->masterPosWait($this->mWaitForPos, $timeout); if ($result == -1 || is_null($result)) { // Timed out waiting for slave, use master instead $msg = __METHOD__ . ": Timed out waiting on {$server} pos {$this->mWaitForPos}"; wfDebugLog('replication', "{$msg}\n"); wfDebugLog('DBPerformance', "{$msg}:\n" . wfBacktrace(true)); $ok = false; } else { wfDebugLog('replication', __METHOD__ . ": Done\n"); $ok = true; // Remember that the DB reached this point $this->srvCache->set($key, $this->mWaitForPos, BagOStuff::TTL_DAY); } if ($close) { $this->closeConnection($conn); } return $ok; }
/** * @param BagOStuff $store * @param array $client Map of (ip: <IP>, agent: <user-agent>) * @since 1.27 */ public function __construct(BagOStuff $store, array $client) { $this->store = $store; $this->client = $client; $this->key = $store->makeGlobalKey('ChronologyProtector', md5($client['ip'] . "\n" . $client['agent'])); }
private function getCacheKey(array $serverIndexes) { sort($serverIndexes); // Lag is per-server, not per-DB, so key on the master DB name return $this->srvCache->makeGlobalKey('lag-times', self::VERSION, $this->parent->getServerName($this->parent->getWriterIndex()), implode('-', $serverIndexes)); }
private function getLagTimeCacheKey() { $writerIndex = $this->parent->getWriterIndex(); // Lag is per-server, not per-DB, so key on the master DB name return $this->srvCache->makeGlobalKey('lag-times', $this->parent->getServerName($writerIndex)); }
/** * @param BagOStuff $store * @param string $dbName * @return string */ private function getTouchedKey(BagOStuff $store, $dbName) { return $store->makeGlobalKey(__CLASS__, 'mtime', $this->clientId, $dbName); }