Dependency cleanups to FileBackendStore
* Inject a PSR logger in place of wf* logging methods. * Replace wfTimestamp() call with ConvertableTimestamp. * Inject the Profiler object. * Rename $wiki => $domain to avoid "wiki" mentions. * Remove stray FSFile::extractImageSizeInfo() method. Change-Id: I3e3a43d36506bec341dc5727b52f5f5a5d32bff5
This commit is contained in:
parent
bcdf0646ed
commit
81a0e795ec
6 changed files with 108 additions and 82 deletions
|
|
@ -21,6 +21,7 @@
|
|||
* @ingroup FileBackend
|
||||
* @author Aaron Schulz
|
||||
*/
|
||||
use \MediaWiki\Logger\LoggerFactory;
|
||||
|
||||
/**
|
||||
* Class to handle file backend registration
|
||||
|
|
@ -169,6 +170,8 @@ class FileBackendGroup {
|
|||
$config['mimeCallback'] = [ $this, 'guessMimeInternal' ];
|
||||
$config['statusWrapper'] = [ 'Status', 'wrap' ];
|
||||
$config['tmpDirectory'] = wfTempDir();
|
||||
$config['logger'] = LoggerFactory::getInstance( 'FileOperation' );
|
||||
$config['profiler'] = Profiler::instance();
|
||||
|
||||
$this->backends[$name]['instance'] = new $class( $config );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ class FileBackendMultiWrite extends FileBackend {
|
|||
unset( $config['readOnly'] ); // use proxy backend setting
|
||||
unset( $config['fileJournal'] ); // use proxy backend journal
|
||||
unset( $config['lockManager'] ); // lock under proxy backend
|
||||
$config['wikiId'] = $this->wikiId; // use the proxy backend wiki ID
|
||||
$config['domainId'] = $this->domainId; // use the proxy backend wiki ID
|
||||
if ( !empty( $config['isMultiMaster'] ) ) {
|
||||
if ( $this->masterIndex >= 0 ) {
|
||||
throw new LogicException( 'More than one master backend defined.' );
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function createInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
if ( strlen( $params['content'] ) > $this->maxFileSizeInternal() ) {
|
||||
$status = $this->newStatus( 'backend-fail-maxsize',
|
||||
$params['dst'], $this->maxFileSizeInternal() );
|
||||
|
|
@ -157,7 +157,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function storeInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
if ( filesize( $params['src'] ) > $this->maxFileSizeInternal() ) {
|
||||
$status = $this->newStatus( 'backend-fail-maxsize',
|
||||
$params['dst'], $this->maxFileSizeInternal() );
|
||||
|
|
@ -199,7 +199,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function copyInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->doCopyInternal( $params );
|
||||
$this->clearCache( [ $params['dst'] ] );
|
||||
if ( !isset( $params['dstExists'] ) || $params['dstExists'] ) {
|
||||
|
|
@ -231,7 +231,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function deleteInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->doDeleteInternal( $params );
|
||||
$this->clearCache( [ $params['src'] ] );
|
||||
$this->deleteFileCache( $params['src'] ); // persistent cache
|
||||
|
|
@ -265,7 +265,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function moveInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->doMoveInternal( $params );
|
||||
$this->clearCache( [ $params['src'], $params['dst'] ] );
|
||||
$this->deleteFileCache( $params['src'] ); // persistent cache
|
||||
|
|
@ -311,7 +311,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue
|
||||
*/
|
||||
final public function describeInternal( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
if ( count( $params['headers'] ) ) {
|
||||
$status = $this->doDescribeInternal( $params );
|
||||
$this->clearCache( [ $params['src'] ] );
|
||||
|
|
@ -344,7 +344,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function concatenate( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
// Try to lock the source files for the scope of this function
|
||||
|
|
@ -355,7 +355,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
$status->merge( $this->doConcatenate( $params ) );
|
||||
$sec = microtime( true ) - $start_time;
|
||||
if ( !$status->isOK() ) {
|
||||
wfDebugLog( 'FileOperation', get_class( $this ) . "-{$this->name}" .
|
||||
$this->logger->error( get_class( $this ) . "-{$this->name}" .
|
||||
" failed to concatenate " . count( $params['srcs'] ) . " file(s) [$sec sec]" );
|
||||
}
|
||||
}
|
||||
|
|
@ -437,7 +437,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doPrepare( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
|
||||
|
|
@ -450,7 +450,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $shard !== null ) { // confined to a single container/shard
|
||||
$status->merge( $this->doPrepareInternal( $fullCont, $dir, $params ) );
|
||||
} else { // directory is on several shards
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) {
|
||||
$status->merge( $this->doPrepareInternal( "{$fullCont}{$suffix}", $dir, $params ) );
|
||||
|
|
@ -472,7 +472,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doSecure( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
|
||||
|
|
@ -485,7 +485,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $shard !== null ) { // confined to a single container/shard
|
||||
$status->merge( $this->doSecureInternal( $fullCont, $dir, $params ) );
|
||||
} else { // directory is on several shards
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) {
|
||||
$status->merge( $this->doSecureInternal( "{$fullCont}{$suffix}", $dir, $params ) );
|
||||
|
|
@ -507,7 +507,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doPublish( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
|
||||
|
|
@ -520,7 +520,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $shard !== null ) { // confined to a single container/shard
|
||||
$status->merge( $this->doPublishInternal( $fullCont, $dir, $params ) );
|
||||
} else { // directory is on several shards
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) {
|
||||
$status->merge( $this->doPublishInternal( "{$fullCont}{$suffix}", $dir, $params ) );
|
||||
|
|
@ -542,7 +542,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doClean( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
// Recursive: first delete all empty subdirs recursively
|
||||
|
|
@ -575,7 +575,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
$status->merge( $this->doCleanInternal( $fullCont, $dir, $params ) );
|
||||
$this->deleteContainerCache( $fullCont ); // purge cache
|
||||
} else { // directory is on several shards
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) {
|
||||
$status->merge( $this->doCleanInternal( "{$fullCont}{$suffix}", $dir, $params ) );
|
||||
|
|
@ -598,21 +598,21 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function fileExists( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$stat = $this->getFileStat( $params );
|
||||
|
||||
return ( $stat === null ) ? null : (bool)$stat; // null => failure
|
||||
}
|
||||
|
||||
final public function getFileTimestamp( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$stat = $this->getFileStat( $params );
|
||||
|
||||
return $stat ? $stat['mtime'] : false;
|
||||
}
|
||||
|
||||
final public function getFileSize( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$stat = $this->getFileStat( $params );
|
||||
|
||||
return $stat ? $stat['size'] : false;
|
||||
|
|
@ -623,7 +623,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $path === null ) {
|
||||
return false; // invalid storage path
|
||||
}
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$latest = !empty( $params['latest'] ); // use latest data?
|
||||
if ( !$latest && !$this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
|
||||
$this->primeFileCache( [ $path ] ); // check persistent cache
|
||||
|
|
@ -661,9 +661,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
$this->cheapCache->set( $path, 'stat', $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' );
|
||||
$this->cheapCache->set( $path, 'xattr', [ 'map' => false, 'latest' => $latest ] );
|
||||
$this->cheapCache->set( $path, 'sha1', [ 'hash' => false, 'latest' => $latest ] );
|
||||
wfDebug( __METHOD__ . ": File $path does not exist.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": File $path does not exist.\n" );
|
||||
} else { // an error occurred
|
||||
wfDebug( __METHOD__ . ": Could not stat file $path.\n" );
|
||||
$this->logger->warning( __METHOD__ . ": Could not stat file $path.\n" );
|
||||
}
|
||||
|
||||
return $stat;
|
||||
|
|
@ -675,7 +675,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
abstract protected function doGetFileStat( array $params );
|
||||
|
||||
public function getFileContentsMulti( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
$params = $this->setConcurrencyFlags( $params );
|
||||
$contents = $this->doGetFileContentsMulti( $params );
|
||||
|
|
@ -704,7 +704,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $path === null ) {
|
||||
return false; // invalid storage path
|
||||
}
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$latest = !empty( $params['latest'] ); // use latest data?
|
||||
if ( $this->cheapCache->has( $path, 'xattr', self::CACHE_TTL ) ) {
|
||||
$stat = $this->cheapCache->get( $path, 'xattr' );
|
||||
|
|
@ -734,7 +734,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $path === null ) {
|
||||
return false; // invalid storage path
|
||||
}
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$latest = !empty( $params['latest'] ); // use latest data?
|
||||
if ( $this->cheapCache->has( $path, 'sha1', self::CACHE_TTL ) ) {
|
||||
$stat = $this->cheapCache->get( $path, 'sha1' );
|
||||
|
|
@ -765,7 +765,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function getFileProps( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$fsFile = $this->getLocalReference( $params );
|
||||
$props = $fsFile ? $fsFile->getProps() : FSFile::placeholderProps();
|
||||
|
||||
|
|
@ -773,7 +773,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function getLocalReferenceMulti( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
$params = $this->setConcurrencyFlags( $params );
|
||||
|
||||
|
|
@ -816,7 +816,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function getLocalCopyMulti( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
$params = $this->setConcurrencyFlags( $params );
|
||||
$tmpFiles = $this->doGetLocalCopyMulti( $params );
|
||||
|
|
@ -841,7 +841,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function streamFile( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
// Always set some fields for subclass convenience
|
||||
|
|
@ -897,7 +897,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $shard !== null ) { // confined to a single container/shard
|
||||
return $this->doDirectoryExists( $fullCont, $dir, $params );
|
||||
} else { // directory is on several shards
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
$res = false; // response
|
||||
foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) {
|
||||
|
|
@ -933,7 +933,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
// File listing is confined to a single container/shard
|
||||
return $this->getDirectoryListInternal( $fullCont, $dir, $params );
|
||||
} else {
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
// File listing spans multiple containers/shards
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
|
||||
|
|
@ -963,7 +963,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
// File listing is confined to a single container/shard
|
||||
return $this->getFileListInternal( $fullCont, $dir, $params );
|
||||
} else {
|
||||
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": iterating over all container shards.\n" );
|
||||
// File listing spans multiple containers/shards
|
||||
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
|
||||
|
||||
|
|
@ -1059,7 +1059,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doOperationsInternal( array $ops, array $opts ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
// Fix up custom header name/value pairs...
|
||||
|
|
@ -1111,7 +1111,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
$subStatus->success[$i] = false;
|
||||
++$subStatus->failCount;
|
||||
}
|
||||
wfDebugLog( 'FileOperation', get_class( $this ) . "-{$this->name} " .
|
||||
$this->logger->error( get_class( $this ) . "-{$this->name} " .
|
||||
" stat failure; aborted operations: " . FormatJson::encode( $ops ) );
|
||||
}
|
||||
|
||||
|
|
@ -1126,7 +1126,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final protected function doQuickOperationsInternal( array $ops ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$status = $this->newStatus();
|
||||
|
||||
// Fix up custom header name/value pairs...
|
||||
|
|
@ -1193,7 +1193,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return StatusValue[] Map of StatusValue objects
|
||||
*/
|
||||
final public function executeOpHandlesInternal( array $fileOpHandles ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
foreach ( $fileOpHandles as $fileOpHandle ) {
|
||||
if ( !( $fileOpHandle instanceof FileBackendStoreOpHandle ) ) {
|
||||
|
|
@ -1297,7 +1297,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
final public function preloadFileStat( array $params ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
$success = true; // no network errors
|
||||
|
||||
$params['concurrency'] = ( $this->parallelize !== 'off' ) ? $this->concurrency : 1;
|
||||
|
|
@ -1333,10 +1333,10 @@ abstract class FileBackendStore extends FileBackend {
|
|||
[ 'map' => false, 'latest' => $latest ] );
|
||||
$this->cheapCache->set( $path, 'sha1',
|
||||
[ 'hash' => false, 'latest' => $latest ] );
|
||||
wfDebug( __METHOD__ . ": File $path does not exist.\n" );
|
||||
$this->logger->debug( __METHOD__ . ": File $path does not exist.\n" );
|
||||
} else { // an error occurred
|
||||
$success = false;
|
||||
wfDebug( __METHOD__ . ": Could not stat file $path.\n" );
|
||||
$this->logger->warning( __METHOD__ . ": Could not stat file $path.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1566,8 +1566,8 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return string
|
||||
*/
|
||||
final protected function fullContainerName( $container ) {
|
||||
if ( $this->wikiId != '' ) {
|
||||
return "{$this->wikiId}-$container";
|
||||
if ( $this->domainId != '' ) {
|
||||
return "{$this->domainId}-$container";
|
||||
} else {
|
||||
return $container;
|
||||
}
|
||||
|
|
@ -1606,7 +1606,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return string
|
||||
*/
|
||||
private function containerCacheKey( $container ) {
|
||||
return "filebackend:{$this->name}:{$this->wikiId}:container:{$container}";
|
||||
return "filebackend:{$this->name}:{$this->domainId}:container:{$container}";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1639,7 +1639,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @param array $items
|
||||
*/
|
||||
final protected function primeContainerCache( array $items ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
$paths = []; // list of storage paths
|
||||
$contNames = []; // (cache key => resolved container name)
|
||||
|
|
@ -1687,7 +1687,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @return string
|
||||
*/
|
||||
private function fileCacheKey( $path ) {
|
||||
return "filebackend:{$this->name}:{$this->wikiId}:file:" . sha1( $path );
|
||||
return "filebackend:{$this->name}:{$this->domainId}:file:" . sha1( $path );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1703,7 +1703,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
if ( $path === null ) {
|
||||
return; // invalid storage path
|
||||
}
|
||||
$mtime = wfTimestamp( TS_UNIX, $val['mtime'] );
|
||||
$mtime = ConvertibleTimestamp::convert( TS_UNIX, $val['mtime'] );
|
||||
$ttl = $this->memCache->adaptiveTTL( $mtime, 7 * 86400, 300, .1 );
|
||||
$key = $this->fileCacheKey( $path );
|
||||
// Set the cache unless it is currently salted.
|
||||
|
|
@ -1736,7 +1736,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* @param array $items List of storage paths
|
||||
*/
|
||||
final protected function primeFileCache( array $items ) {
|
||||
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
|
||||
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
|
||||
|
||||
$paths = []; // list of storage paths
|
||||
$pathNames = []; // (cache key => storage path)
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ class FileOpBatch {
|
|||
$statuses = [];
|
||||
$opHandles = [];
|
||||
// Get the backend; all sub-batch ops belong to a single backend
|
||||
/** @var FileBackendStore $backend */
|
||||
$backend = reset( $performOpsBatch )->getBackend();
|
||||
// Get the operation handles or actually do it if there is just one.
|
||||
// If attemptAsync() returns a StatusValue, it was either due to an error
|
||||
|
|
|
|||
|
|
@ -153,26 +153,6 @@ class FSFile {
|
|||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exract image size information
|
||||
*
|
||||
* @param array $gis
|
||||
* @return array
|
||||
*/
|
||||
protected function extractImageSizeInfo( array $gis ) {
|
||||
$info = [];
|
||||
# NOTE: $gis[2] contains a code for the image type. This is no longer used.
|
||||
$info['width'] = $gis[0];
|
||||
$info['height'] = $gis[1];
|
||||
if ( isset( $gis['bits'] ) ) {
|
||||
$info['bits'] = $gis['bits'];
|
||||
} else {
|
||||
$info['bits'] = 0;
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
|
||||
* encoding, zero padded to 31 digits.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
* @ingroup FileBackend
|
||||
* @author Aaron Schulz
|
||||
*/
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @brief Base class for all file backend classes (including multi-write backends).
|
||||
|
|
@ -36,16 +38,21 @@
|
|||
* Outside callers can assume that all backends will have these functions.
|
||||
*
|
||||
* All "storage paths" are of the format "mwstore://<backend>/<container>/<path>".
|
||||
* The "backend" portion is unique name for MediaWiki to refer to a backend, while
|
||||
* The "backend" portion is unique name for the application to refer to a backend, while
|
||||
* the "container" portion is a top-level directory of the backend. The "path" portion
|
||||
* is a relative path that uses UNIX file system (FS) notation, though any particular
|
||||
* backend may not actually be using a local filesystem. Therefore, the relative paths
|
||||
* are only virtual.
|
||||
*
|
||||
* Backend contents are stored under wiki-specific container names by default.
|
||||
* Global (qualified) backends are achieved by configuring the "wiki ID" to a constant.
|
||||
* Backend contents are stored under "domain"-specific container names by default.
|
||||
* A domain is simply a logical umbrella for entities, such as those belonging to a certain
|
||||
* application or portion of a website, for example. A domain can be local or global.
|
||||
* Global (qualified) backends are achieved by configuring the "domain ID" to a constant.
|
||||
* Global domains are simpler, but local domains can be used by choosing a domain ID based on
|
||||
* the current context, such as which language of a website is being used.
|
||||
*
|
||||
* For legacy reasons, the FSFileBackend class allows manually setting the paths of
|
||||
* containers to ones that do not respect the "wiki ID".
|
||||
* containers to ones that do not respect the "domain ID".
|
||||
*
|
||||
* In key/value (object) stores, containers are the only hierarchy (the rest is emulated).
|
||||
* FS-based backends are somewhat more restrictive due to the existence of real
|
||||
|
|
@ -82,12 +89,12 @@
|
|||
* @ingroup FileBackend
|
||||
* @since 1.19
|
||||
*/
|
||||
abstract class FileBackend {
|
||||
abstract class FileBackend implements LoggerAwareInterface {
|
||||
/** @var string Unique backend name */
|
||||
protected $name;
|
||||
|
||||
/** @var string Unique wiki name */
|
||||
protected $wikiId;
|
||||
/** @var string Unique domain name */
|
||||
protected $domainId;
|
||||
|
||||
/** @var string Read-only explanation message */
|
||||
protected $readOnly;
|
||||
|
|
@ -103,9 +110,12 @@ abstract class FileBackend {
|
|||
|
||||
/** @var LockManager */
|
||||
protected $lockManager;
|
||||
|
||||
/** @var FileJournal */
|
||||
protected $fileJournal;
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
/** @var object|string Class name or object With profileIn/profileOut methods */
|
||||
protected $profiler;
|
||||
|
||||
/** @var callable */
|
||||
protected $statusWrapper;
|
||||
|
|
@ -124,7 +134,7 @@ abstract class FileBackend {
|
|||
* This should consist of alphanumberic, '-', and '_' characters.
|
||||
* This name should not be changed after use (e.g. with journaling).
|
||||
* Note that the name is *not* used in actual container names.
|
||||
* - wikiId : Prefix to container names that is unique to this backend.
|
||||
* - domainId : Prefix to container names that is unique to this backend.
|
||||
* It should only consist of alphanumberic, '-', and '_' characters.
|
||||
* This ID is what avoids collisions if multiple logical backends
|
||||
* use the same storage system, so this should be set carefully.
|
||||
|
|
@ -139,15 +149,20 @@ abstract class FileBackend {
|
|||
* - concurrency : How many file operations can be done in parallel.
|
||||
* - tmpDirectory : Directory to use for temporary files. If this is not set or null,
|
||||
* then the backend will try to discover a usable temporary directory.
|
||||
* - logger : Optional PSR logger object.
|
||||
* - profiler : Optional class name or object With profileIn/profileOut methods.
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct( array $config ) {
|
||||
$this->name = $config['name'];
|
||||
$this->wikiId = $config['wikiId']; // e.g. "my_wiki-en_"
|
||||
$this->domainId = isset( $config['domainId'] )
|
||||
? $config['domainId'] // e.g. "my_wiki-en_"
|
||||
: $config['wikiId']; // b/c alias
|
||||
if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
|
||||
throw new InvalidArgumentException( "Backend name '{$this->name}' is invalid." );
|
||||
} elseif ( !is_string( $this->wikiId ) ) {
|
||||
throw new InvalidArgumentException( "Backend wiki ID not provided for '{$this->name}'." );
|
||||
} elseif ( !is_string( $this->domainId ) ) {
|
||||
throw new InvalidArgumentException(
|
||||
"Backend domain ID not provided for '{$this->name}'." );
|
||||
}
|
||||
$this->lockManager = isset( $config['lockManager'] )
|
||||
? $config['lockManager']
|
||||
|
|
@ -164,10 +179,16 @@ abstract class FileBackend {
|
|||
$this->concurrency = isset( $config['concurrency'] )
|
||||
? (int)$config['concurrency']
|
||||
: 50;
|
||||
$this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
|
||||
$this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
|
||||
$this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
|
||||
$this->tmpDirectory = isset( $config['tmpDirectory'] ) ? $config['tmpDirectory'] : null;
|
||||
}
|
||||
|
||||
public function setLogger( LoggerInterface $logger ) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique backend name.
|
||||
* We may have multiple different backends of the same type.
|
||||
|
|
@ -180,14 +201,22 @@ abstract class FileBackend {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the wiki identifier used for this backend (possibly empty).
|
||||
* Note that this might *not* be in the same format as wfWikiID().
|
||||
* Get the domain identifier used for this backend (possibly empty).
|
||||
*
|
||||
* @return string
|
||||
* @since 1.28
|
||||
*/
|
||||
final public function getDomainId() {
|
||||
return $this->domainId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias to getDomainId()
|
||||
* @return string
|
||||
* @since 1.20
|
||||
*/
|
||||
final public function getWikiId() {
|
||||
return $this->wikiId;
|
||||
return $this->getDomainId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1569,4 +1598,17 @@ abstract class FileBackend {
|
|||
final protected function wrapStatus( StatusValue $sv ) {
|
||||
return $this->statusWrapper ? call_user_func( $this->statusWrapper, $sv ) : $sv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $section
|
||||
* @return ScopedCallback|null
|
||||
*/
|
||||
protected function scopedProfileSection( $section ) {
|
||||
if ( $this->profiler ) {
|
||||
call_user_func( [ $this->profiler, 'profileIn' ], $section );
|
||||
return new ScopedCallback( [ $this->profiler, 'profileOut' ] );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue