本文整理汇总了PHP中BagOStuff类的典型用法代码示例。如果您正苦于以下问题:PHP BagOStuff类的具体用法?PHP BagOStuff怎么用?PHP BagOStuff使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了BagOStuff类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: __construct
/**
* $params include:
* - caches: This should have a numbered array of cache parameter
* structures, in the style required by $wgObjectCaches. See
* the documentation of $wgObjectCaches for more detail.
* BagOStuff objects can also be used as values.
* The first cache is the primary one, being the first to
* be read in the fallback chain. Writes happen to all stores
* in the order they are defined. However, lock()/unlock() calls
* only use the primary store.
* - replication: Either 'sync' or 'async'. This controls whether writes to
* secondary stores are deferred when possible. Async writes
* require the HHVM register_postsend_function() function.
* Async writes can increase the chance of some race conditions
* or cause keys to expire seconds later than expected. It is
* safe to use for modules when cached values: are immutable,
* invalidation uses logical TTLs, invalidation uses etag/timestamp
* validation against the DB, or merge() is used to handle races.
*
* @param array $params
* @throws InvalidArgumentException
*/
public function __construct($params)
{
parent::__construct($params);
if (empty($params['caches']) || !is_array($params['caches'])) {
throw new InvalidArgumentException(__METHOD__ . ': "caches" parameter must be an array of caches');
}
$this->caches = array();
foreach ($params['caches'] as $cacheInfo) {
$this->caches[] = $cacheInfo instanceof BagOStuff ? $cacheInfo : ObjectCache::newFromParams($cacheInfo);
}
$this->asyncWrites = isset($params['replication']) && $params['replication'] === 'async';
}
示例2: doWait
/**
* 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;
}
示例3: testGetScopedLock
/**
* @covers BagOStuff::getScopedLock
*/
public function testGetScopedLock()
{
$key = wfMemcKey('test');
$value1 = $this->cache->getScopedLock($key, 0);
$value2 = $this->cache->getScopedLock($key, 0);
$this->assertType(ScopedCallback::class, $value1, 'First call returned lock');
$this->assertNull($value2, 'Duplicate call returned no lock');
unset($value1);
$value3 = $this->cache->getScopedLock($key, 0);
$this->assertType(ScopedCallback::class, $value3, 'Lock returned callback after release');
unset($value3);
$value1 = $this->cache->getScopedLock($key, 0, 5, 'reentry');
$value2 = $this->cache->getScopedLock($key, 0, 5, 'reentry');
$this->assertType(ScopedCallback::class, $value1, 'First reentrant call returned lock');
$this->assertType(ScopedCallback::class, $value1, 'Second reentrant call returned lock');
}
示例4: doGetAllReadyWikiQueues
/**
* @see JobQueueAggregator::doAllGetReadyWikiQueues()
*/
protected function doGetAllReadyWikiQueues()
{
$key = $this->getReadyQueueCacheKey();
// If the cache entry wasn't present, is stale, or in .1% of cases otherwise,
// regenerate the cache. Use any available stale cache if another process is
// currently regenerating the pending DB information.
$pendingDbInfo = $this->cache->get($key);
if (!is_array($pendingDbInfo) || time() - $pendingDbInfo['timestamp'] > $this->cacheTTL || mt_rand(0, 999) == 0) {
if ($this->cache->add("{$key}:rebuild", 1, 1800)) {
// lock
$pendingDbInfo = array('pendingDBs' => $this->findPendingWikiQueues(), 'timestamp' => time());
for ($attempts = 1; $attempts <= 25; ++$attempts) {
if ($this->cache->add("{$key}:lock", 1, 60)) {
// lock
$this->cache->set($key, $pendingDbInfo);
$this->cache->delete("{$key}:lock");
// unlock
break;
}
}
$this->cache->delete("{$key}:rebuild");
// unlock
}
}
return is_array($pendingDbInfo) ? $pendingDbInfo['pendingDBs'] : array();
// cache is both empty and locked
}
示例5: initPositions
/**
* Load in previous master positions for the client
*/
protected function initPositions()
{
if ($this->initialized) {
return;
}
$this->initialized = true;
if ($this->wait) {
// If there is an expectation to see master positions with a certain min
// timestamp, then block until they appear, or until a timeout is reached.
if ($this->waitForPosTime > 0.0) {
$data = null;
$loop = new WaitConditionLoop(function () use(&$data) {
$data = $this->store->get($this->key);
return self::minPosTime($data) >= $this->waitForPosTime ? WaitConditionLoop::CONDITION_REACHED : WaitConditionLoop::CONDITION_CONTINUE;
}, $this->waitForPosTimeout);
$result = $loop->invoke();
$waitedMs = $loop->getLastWaitTime() * 1000.0;
if ($result == $loop::CONDITION_REACHED) {
$msg = "expected and found pos time {$this->waitForPosTime} ({$waitedMs}ms)";
$this->logger->debug($msg);
} else {
$msg = "expected but missed pos time {$this->waitForPosTime} ({$waitedMs}ms)";
$this->logger->info($msg);
}
} else {
$data = $this->store->get($this->key);
}
$this->startupPositions = $data ? $data['positions'] : [];
$this->logger->info(__METHOD__ . ": key is {$this->key} (read)\n");
} else {
$this->startupPositions = [];
$this->logger->info(__METHOD__ . ": key is {$this->key} (unread)\n");
}
}
示例6: __construct
/**
* Constructor. Parameters are:
* - server: A server info structure in the format required by each
* element in $wgDBServers.
*
* - servers: An array of server info structures describing a set of
* database servers to distribute keys to. If this is
* specified, the "server" option will be ignored.
*
* - purgePeriod: The average number of object cache requests in between
* garbage collection operations, where expired entries
* are removed from the database. Or in other words, the
* reciprocal of the probability of purging on any given
* request. If this is set to zero, purging will never be
* done.
*
* - tableName: The table name to use, default is "objectcache".
*
* - shards: The number of tables to use for data storage on each server.
* If this is more than 1, table names will be formed in the style
* objectcacheNNN where NNN is the shard index, between 0 and
* shards-1. The number of digits will be the minimum number
* required to hold the largest shard index. Data will be
* distributed across all tables by key hash. This is for
* MySQL bugs 61735 and 61736.
*
* @param array $params
*/
public function __construct($params)
{
parent::__construct($params);
if (isset($params['servers'])) {
$this->serverInfos = $params['servers'];
$this->numServers = count($this->serverInfos);
$this->serverNames = array();
foreach ($this->serverInfos as $i => $info) {
$this->serverNames[$i] = isset($info['host']) ? $info['host'] : "#{$i}";
}
} elseif (isset($params['server'])) {
$this->serverInfos = array($params['server']);
$this->numServers = count($this->serverInfos);
} else {
$this->serverInfos = false;
$this->numServers = 1;
}
if (isset($params['purgePeriod'])) {
$this->purgePeriod = intval($params['purgePeriod']);
}
if (isset($params['tableName'])) {
$this->tableName = $params['tableName'];
}
if (isset($params['shards'])) {
$this->shards = intval($params['shards']);
}
}
示例7: save
/**
* @param ParserOutput $parserOutput
* @param WikiPage $page
* @param ParserOptions $popts
* @param string $cacheTime Time when the cache was generated
* @param int $revId Revision ID that was parsed
*/
public function save($parserOutput, $page, $popts, $cacheTime = null, $revId = null)
{
$expire = $parserOutput->getCacheExpiry();
if ($expire > 0) {
$cacheTime = $cacheTime ?: wfTimestampNow();
if (!$revId) {
$revision = $page->getRevision();
$revId = $revision ? $revision->getId() : null;
}
$optionsKey = new CacheTime();
$optionsKey->mUsedOptions = $parserOutput->getUsedOptions();
$optionsKey->updateCacheExpiry($expire);
$optionsKey->setCacheTime($cacheTime);
$parserOutput->setCacheTime($cacheTime);
$optionsKey->setCacheRevisionId($revId);
$parserOutput->setCacheRevisionId($revId);
$parserOutputKey = $this->getParserOutputKey($page, $popts->optionsHash($optionsKey->mUsedOptions, $page->getTitle()));
// Save the timestamp so that we don't have to load the revision row on view
$parserOutput->setTimestamp($page->getTimestamp());
$msg = "Saved in parser cache with key {$parserOutputKey}" . " and timestamp {$cacheTime}" . " and revision id {$revId}" . "\n";
$parserOutput->mText .= "\n<!-- {$msg} -->\n";
wfDebug($msg);
// Save the parser output
$this->mMemc->set($parserOutputKey, $parserOutput, $expire);
// ...and its pointer
$this->mMemc->set($this->getOptionsKey($page), $optionsKey, $expire);
Hooks::run('ParserCacheSaveComplete', array($this, $parserOutput, $page->getTitle(), $popts, $revId));
} else {
wfDebug("Parser output was marked as uncacheable and has not been saved.\n");
}
}
示例8: recycleAndDeleteStaleJobs
/**
* Recycle or destroy any jobs that have been claimed for too long
*
* @return int Number of jobs recycled/deleted
*/
public function recycleAndDeleteStaleJobs()
{
$now = time();
$count = 0;
// affected rows
$dbw = $this->getMasterDB();
try {
if (!$dbw->lock("jobqueue-recycle-{$this->type}", __METHOD__, 1)) {
return $count;
// already in progress
}
// Remove claims on jobs acquired for too long if enabled...
if ($this->claimTTL > 0) {
$claimCutoff = $dbw->timestamp($now - $this->claimTTL);
// Get the IDs of jobs that have be claimed but not finished after too long.
// These jobs can be recycled into the queue by expiring the claim. Selecting
// the IDs first means that the UPDATE can be done by primary key (less deadlocks).
$res = $dbw->select('job', 'job_id', array('job_cmd' => $this->type, "job_token != {$dbw->addQuotes('')}", "job_token_timestamp < {$dbw->addQuotes($claimCutoff)}", "job_attempts < {$dbw->addQuotes($this->maxTries)}"), __METHOD__);
$ids = array_map(function ($o) {
return $o->job_id;
}, iterator_to_array($res));
if (count($ids)) {
// Reset job_token for these jobs so that other runners will pick them up.
// Set the timestamp to the current time, as it is useful to now that the job
// was already tried before (the timestamp becomes the "released" time).
$dbw->update('job', array('job_token' => '', 'job_token_timestamp' => $dbw->timestamp($now)), array('job_id' => $ids), __METHOD__);
$affected = $dbw->affectedRows();
$count += $affected;
JobQueue::incrStats('job-recycle', $this->type, $affected, $this->wiki);
// The tasks recycled jobs or release delayed jobs into the queue
$this->cache->set($this->getCacheKey('empty'), 'false', self::CACHE_TTL_LONG);
$this->aggr->notifyQueueNonEmpty($this->wiki, $this->type);
}
}
// Just destroy any stale jobs...
$pruneCutoff = $dbw->timestamp($now - self::MAX_AGE_PRUNE);
$conds = array('job_cmd' => $this->type, "job_token != {$dbw->addQuotes('')}", "job_token_timestamp < {$dbw->addQuotes($pruneCutoff)}");
if ($this->claimTTL > 0) {
// only prune jobs attempted too many times...
$conds[] = "job_attempts >= {$dbw->addQuotes($this->maxTries)}";
}
// Get the IDs of jobs that are considered stale and should be removed. Selecting
// the IDs first means that the UPDATE can be done by primary key (less deadlocks).
$res = $dbw->select('job', 'job_id', $conds, __METHOD__);
$ids = array_map(function ($o) {
return $o->job_id;
}, iterator_to_array($res));
if (count($ids)) {
$dbw->delete('job', array('job_id' => $ids), __METHOD__);
$affected = $dbw->affectedRows();
$count += $affected;
JobQueue::incrStats('job-abandon', $this->type, $affected, $this->wiki);
}
$dbw->unlock("jobqueue-recycle-{$this->type}", __METHOD__);
} catch (DBError $e) {
$this->throwDBException($e);
}
return $count;
}
示例9: isset
/**
* @param array $params Additional parameters include:
* - maxKeys : only allow this many keys (using oldest-first eviction)
*/
function __construct($params = [])
{
parent::__construct($params);
$this->maxCacheKeys = isset($params['maxKeys']) ? $params['maxKeys'] : INF;
if ($this->maxCacheKeys <= 0) {
throw new InvalidArgumentException('$maxKeys parameter must be above zero');
}
}
示例10: doFlushCaches
protected function doFlushCaches()
{
static $types = array('empty', 'size', 'acquiredcount', 'delayedcount', 'abandonedcount');
foreach ($types as $type) {
$this->cache->delete($this->getCacheKey($type));
}
foreach ($this->partitionQueues as $queue) {
$queue->doFlushCaches();
}
}
示例11: closeConnection
/**
* Close the connection to the Swift proxy
*
* @return void
*/
protected function closeConnection()
{
if ($this->conn) {
$this->srvCache->delete($this->getCredsCacheKey($this->auth->username));
$this->conn->close();
// close active cURL handles in CF_Http object
$this->conn = null;
$this->connStarted = 0;
}
}
示例12: getFileContentsHashInternal
/**
* 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;
}
示例13: onError
/**
* Log an unexpected exception for this backend.
* This also sets the Status object to have a fatal error.
*
* @param Status|null $status
* @param string $func
* @param array $params
* @param string $err Error string
* @param int $code HTTP status
* @param string $desc HTTP status description
*/
public function onError($status, $func, array $params, $err = '', $code = 0, $desc = '')
{
if ($status instanceof Status) {
$status->fatal('backend-fail-internal', $this->name);
}
if ($code == 401) {
// possibly a stale token
$this->srvCache->delete($this->getCredsCacheKey($this->swiftUser));
}
wfDebugLog('SwiftBackend', "HTTP {$code} ({$desc}) in '{$func}' (given '" . FormatJson::encode($params) . "')" . ($err ? ": {$err}" : ""));
}
示例14: __construct
/**
* Constructor. Parameters are:
*
* - caches: This should have a numbered array of cache parameter
* structures, in the style required by $wgObjectCaches. See
* the documentation of $wgObjectCaches for more detail.
*
* @param array $params
* @throws InvalidArgumentException
*/
public function __construct($params)
{
parent::__construct($params);
if (!isset($params['caches'])) {
throw new InvalidArgumentException(__METHOD__ . ': the caches parameter is required');
}
$this->caches = array();
foreach ($params['caches'] as $cacheInfo) {
$this->caches[] = ObjectCache::newFromParams($cacheInfo);
}
}
示例15: getFileContentsHashInternal
/**
* 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 = MediaWiki\quietCall('filemtime', $filePath);
if ($mtime === false) {
return false;
}
$cacheKey = wfGlobalCacheKey(__CLASS__, $filePath, $mtime, $algo);
$hash = $this->cache->get($cacheKey);
if ($hash) {
return $hash;
}
$contents = MediaWiki\quietCall('file_get_contents', $filePath);
if ($contents === false) {
return false;
}
$hash = hash($algo, $contents);
$this->cache->set($cacheKey, $hash, 60 * 60 * 24);
// 24h
return $hash;
}