* @file
* @ingroup FileBackend
*/
+use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Wikimedia\ScopedCallback;
/** @var int How many operations can be done in parallel */
protected $concurrency;
- /** @var string Temporary file directory */
- protected $tmpDirectory;
+ /** @var TempFSFileFactory */
+ protected $tmpFileFactory;
/** @var LockManager */
protected $lockManager;
const ATTR_METADATA = 2; // files can be stored with metadata key/values
const ATTR_UNICODE_PATHS = 4; // files can have Unicode paths (not just ASCII)
+ /** @var null Idiom for "could not determine due to I/O errors" */
+ const UNKNOWN = null;
+
/**
* Create a new backend instance from configuration.
* This should only be called from within FileBackendGroup.
* - parallelize : When to do file operations in parallel (when possible).
* Allowed values are "implicit", "explicit" and "off".
* - 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.
+ * - tmpDirectory : Directory to use for temporary files.
+ * - tmpFileFactory : Optional TempFSFileFactory object. Only has an effect if tmpDirectory is
+ * not set. If both are unset or null, then the backend will try to discover a usable
+ * temporary directory.
* - obResetFunc : alternative callback to clear the output buffer
* - streamMimeFunc : alternative method to determine the content type from the path
* - logger : Optional PSR logger object.
}
$this->logger = $config['logger'] ?? new NullLogger();
$this->statusWrapper = $config['statusWrapper'] ?? null;
- $this->tmpDirectory = $config['tmpDirectory'] ?? null;
+ // tmpDirectory gets precedence for backward compatibility
+ if ( isset( $config['tmpDirectory'] ) ) {
+ $this->tmpFileFactory = new TempFSFileFactory( $config['tmpDirectory'] );
+ } else {
+ $this->tmpFileFactory = $config['tmpFileFactory'] ?? new TempFSFileFactory();
+ }
}
public function setLogger( LoggerInterface $logger ) {
}
/**
- * Get the unique backend name.
+ * Get the unique backend name
+ *
* We may have multiple different backends of the same type.
* For example, we can have two Swift backends using different proxies.
*
/**
* Alias to getDomainId()
+ *
* @return string
* @since 1.20
* @deprecated Since 1.34 Use getDomainId()
*
* The StatusValue will be "OK" unless:
* - a) unexpected operation errors occurred (network partitions, disk full...)
- * - b) significant operation errors occurred and 'force' was not set
+ * - b) predicted operation errors occurred and 'force' was not set
*
* @param array $ops List of operations to execute in order
* @param array $opts Batch operation options
abstract public function getFileHttpUrl( array $params );
/**
- * Check if a directory exists at a given storage path.
- * Backends using key/value stores will check if the path is a
- * virtual directory, meaning there are files under the given directory.
+ * Check if a directory exists at a given storage path
+ *
+ * For backends using key/value stores, a directory is said to exist whenever
+ * there exist any files with paths using the given directory path as a prefix
+ * followed by a forward slash. For example, if there is a file called
+ * "mwstore://backend/container/dir/path.svg" then directories are said to exist
+ * at "mwstore://backend/container" and "mwstore://backend/container/dir". These
+ * can be thought of as "virtual" directories.
+ *
+ * Backends that directly use a filesystem layer might enumerate empty directories.
+ * The clean() method should always be used when files are deleted or moved if this
+ * is a concern. This is a trade-off to avoid write amplication/contention on file
+ * changes or read amplification when calling this method.
*
* Storage backends with eventual consistency might return stale data.
*
+ * @see FileBackend::clean()
+ *
* @param array $params Parameters include:
* - dir : storage directory
- * @return bool|null Returns null on failure
+ * @return bool|null Whether a directory exists or null on failure
* @since 1.20
*/
abstract public function directoryExists( array $params );
/**
- * Get an iterator to list *all* directories under a storage directory.
+ * Get an iterator to list *all* directories under a storage directory
+ *
* If the directory is of the form "mwstore://backend/container",
* then all directories in the container will be listed.
* If the directory is of form "mwstore://backend/container/dir",
*
* Failures during iteration can result in FileBackendError exceptions (since 1.22).
*
+ * @see FileBackend::directoryExists()
+ *
* @param array $params Parameters include:
* - dir : storage directory
* - topOnly : only return direct child dirs of the directory
- * @return Traversable|array|null Returns null on failure
+ * @return Traversable|array|null Directory list enumerator null on failure
* @since 1.20
*/
abstract public function getDirectoryList( array $params );
*
* Failures during iteration can result in FileBackendError exceptions (since 1.22).
*
+ * @see FileBackend::directoryExists()
+ *
* @param array $params Parameters include:
* - dir : storage directory
- * @return Traversable|array|null Returns null on failure
+ * @return Traversable|array|null Directory list enumerator or null on failure
* @since 1.20
*/
final public function getTopDirectoryList( array $params ) {
}
/**
- * Get an iterator to list *all* stored files under a storage directory.
- * If the directory is of the form "mwstore://backend/container",
- * then all files in the container will be listed.
- * If the directory is of form "mwstore://backend/container/dir",
- * then all files under that directory will be listed.
- * Results will be storage paths relative to the given directory.
+ * Get an iterator to list *all* stored files under a storage directory
+ *
+ * If the directory is of the form "mwstore://backend/container", then all
+ * files in the container will be listed. If the directory is of form
+ * "mwstore://backend/container/dir", then all files under that directory will
+ * be listed. Results will be storage paths relative to the given directory.
*
* Storage backends with eventual consistency might return stale data.
*
* - dir : storage directory
* - topOnly : only return direct child files of the directory (since 1.20)
* - adviseStat : set to true if stat requests will be made on the files (since 1.22)
- * @return Traversable|array|null Returns null on failure
+ * @return Traversable|array|null File list enumerator or null on failure
*/
abstract public function getFileList( array $params );
* @param array $params Parameters include:
* - dir : storage directory
* - adviseStat : set to true if stat requests will be made on the files (since 1.22)
- * @return Traversable|array|null Returns null on failure
+ * @return Traversable|array|null File list enumerator or null on failure
* @since 1.20
*/
final public function getTopFileList( array $params ) {
* @param array $params Parameters include:
* - srcs : list of source storage paths
* - latest : use the latest available data
- * @return bool All requests proceeded without I/O errors (since 1.24)
+ * @return bool Whether all requests proceeded without I/O errors (since 1.24)
* @since 1.23
*/
abstract public function preloadFileStat( array $params );
*
* @param string $type One of (attachment, inline)
* @param string $filename Suggested file name (should not contain slashes)
- * @throws FileBackendError
+ * @throws InvalidArgumentException
* @return string
* @since 1.20
*/