* In doOperations(), ignore 'nonLocking' unless 'ignoreErrors' is set. Split out a doOperationsInternal() function so the sanity check could go in doOperations().
* Moved getFileList() down a bit.
* Documentation tweaks.
* exists at the destination that has the same
* contents as the new contents to be written there.
*
* exists at the destination that has the same
* contents as the new contents to be written there.
*
- * $opts is an associative of options, including:
+ * $opts is an associative of boolean flags, including:
+ * 'ignoreErrors' : Errors that would normally cause a rollback do not.
+ * The remaining operations are still attempted if any fail.
* 'nonLocking' : No locks are acquired for the operations.
* This can increase performance for non-critical writes.
* 'nonLocking' : No locks are acquired for the operations.
* This can increase performance for non-critical writes.
- * 'ignoreErrors' : Serious errors that would normally cause a rollback
- * do not. The remaining operations are still attempted.
+ * This has no effect unless the 'ignoreErrors' flag is set.
+ * 'allowStale' : Don't require the latest available data.
+ * This can increase performance for non-critical writes.
+ * This has no effect unless the 'ignoreErrors' flag is set.
*
* Return value:
* This returns a Status, which contains all warnings and fatals that occured
*
* Return value:
* This returns a Status, which contains all warnings and fatals that occured
* @param $opts Array Batch operation options
* @return Status
*/
* @param $opts Array Batch operation options
* @return Status
*/
- abstract public function doOperations( array $ops, array $opts = array() );
+ final public function doOperations( array $ops, array $opts = array() ) {
+ if ( empty( $opts['ignoreErrors'] ) ) { // sanity
+ unset( $opts['nonLocking'] );
+ unset( $opts['allowStale'] );
+ }
+ return $this->doOperationsInternal( $ops, $opts );
+ }
+
+ /**
+ * @see FileBackendBase::doOperations()
+ */
+ abstract protected function doOperationsInternal( array $ops, array $opts );
/**
* Same as doOperations() except it takes a single operation.
/**
* Same as doOperations() except it takes a single operation.
* Check if a file exists at a storage path in the backend.
*
* $params include:
* Check if a file exists at a storage path in the backend.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return bool
*
* @param $params Array
* @return bool
* Get a SHA-1 hash of the file at a storage path in the backend.
*
* $params include:
* Get a SHA-1 hash of the file at a storage path in the backend.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return string|false Hash string or false on failure
*
* @param $params Array
* @return string|false Hash string or false on failure
* Get the last-modified timestamp of the file at a storage path.
*
* $params include:
* Get the last-modified timestamp of the file at a storage path.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return string|false TS_MW timestamp or false on failure
*
* @param $params Array
* @return string|false TS_MW timestamp or false on failure
* Returns FSFile::placeholderProps() on failure.
*
* $params include:
* Returns FSFile::placeholderProps() on failure.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return Array
*
* @param $params Array
* @return Array
* $params include:
* src : source storage path
* headers : additional HTTP headers to send on success
* $params include:
* src : source storage path
* headers : additional HTTP headers to send on success
+ * latest : use the latest available data
*
* @param $params Array
* @return Status
*/
abstract public function streamFile( array $params );
*
* @param $params Array
* @return Status
*/
abstract public function streamFile( array $params );
- /**
- * Get an iterator to list out all object files under a storage directory.
- * If the directory is of the form "mwstore://container", then all items in
- * the container should be listed. If of the form "mwstore://container/dir",
- * then all items under that container directory should be listed.
- * Results should be storage paths relative to the given directory.
- *
- * $params include:
- * dir : storage path directory
- *
- * @return Traversable|Array|null Returns null on failure
- */
- abstract public function getFileList( array $params );
-
/**
* Returns a file system file, identical to the file at a storage path.
* The file returned is either:
/**
* Returns a file system file, identical to the file at a storage path.
* The file returned is either:
* In that later case, there are copies of the file that must stay in sync.
*
* $params include:
* In that later case, there are copies of the file that must stay in sync.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return FSFile|null Returns null on failure
*
* @param $params Array
* @return FSFile|null Returns null on failure
* Temporary files may be purged when the file object falls out of scope.
*
* $params include:
* Temporary files may be purged when the file object falls out of scope.
*
* $params include:
- * src : source storage path
+ * src : source storage path
+ * latest : use the latest available data
*
* @param $params Array
* @return TempFSFile|null Returns null on failure
*/
abstract public function getLocalCopy( array $params );
*
* @param $params Array
* @return TempFSFile|null Returns null on failure
*/
abstract public function getLocalCopy( array $params );
+ /**
+ * Get an iterator to list out all object files under a storage directory.
+ * If the directory is of the form "mwstore://container", then all items in
+ * the container should be listed. If of the form "mwstore://container/dir",
+ * then all items under that container directory should be listed.
+ * Results should be storage paths relative to the given directory.
+ *
+ * $params include:
+ * dir : storage path directory
+ *
+ * @return Traversable|Array|null Returns null on failure
+ */
+ abstract public function getFileList( array $params );
+
/**
* Lock the files at the given storage paths in the backend.
* This will either lock all the files or none (on failure).
/**
* Lock the files at the given storage paths in the backend.
* This will either lock all the files or none (on failure).
/**
* Return a list of FileOp objects from a list of operations.
/**
* Return a list of FileOp objects from a list of operations.
+ * Do not call this function from places outside FileBackend.
+ *
* The result must have the same number of items as the input.
* An exception is thrown if an unsupported operation is requested.
*
* The result must have the same number of items as the input.
* An exception is thrown if an unsupported operation is requested.
*
- * @see FileBackendBase::doOperations()
+ * @see FileBackendBase::doOperationsInternal()
- final public function doOperations( array $ops, array $opts = array() ) {
+ protected function doOperationsInternal( array $ops, array $opts ) {
$status = Status::newGood();
// Build up a list of FileOps...
$performOps = $this->getOperations( $ops );
$status = Status::newGood();
// Build up a list of FileOps...
$performOps = $this->getOperations( $ops );
+ // Acquire any locks as needed...
if ( empty( $opts['nonLocking'] ) ) {
// Build up a list of files to lock...
$filesLockEx = $filesLockSh = array();
if ( empty( $opts['nonLocking'] ) ) {
// Build up a list of files to lock...
$filesLockEx = $filesLockSh = array();
* registered to this proxy backend and it will act as a single backend.
* Use this when all access to those backends is through this proxy backend.
* At least one of the backends must be declared the "master" backend.
* registered to this proxy backend and it will act as a single backend.
* Use this when all access to those backends is through this proxy backend.
* At least one of the backends must be declared the "master" backend.
+ *
+ * Only use this class when transitioning from one storage system to another.
*
* The order that the backends are defined sets the priority of which
* backend is read from or written to first. Functions like fileExists()
*
* The order that the backends are defined sets the priority of which
* backend is read from or written to first. Functions like fileExists()
- final public function doOperations( array $ops, array $opts = array() ) {
+ /**
+ * @see FileBackendBase::doOperationsInternal()
+ */
+ final protected function doOperationsInternal( array $ops, array $opts ) {
$status = Status::newGood();
$performOps = array(); // list of FileOp objects
$status = Status::newGood();
$performOps = array(); // list of FileOp objects
+ /**
+ * @see FileBackendBase::prepare()
+ */
function prepare( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
function prepare( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::secure()
+ */
function secure( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
function secure( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::clean()
+ */
function clean( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
function clean( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::fileExists()
+ */
function fileExists( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
function fileExists( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::getFileTimestamp()
+ */
function getFileTimestamp( array $params ) {
// Skip non-master for consistent timestamps
$realParams = $this->substOpPaths( $params, $backend );
return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams );
}
function getFileTimestamp( array $params ) {
// Skip non-master for consistent timestamps
$realParams = $this->substOpPaths( $params, $backend );
return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams );
}
+ /**
+ * @see FileBackendBase::getFileSha1Base36()
+ */
function getFileSha1Base36( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
function getFileSha1Base36( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::getFileProps()
+ */
function getFileProps( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
function getFileProps( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::streamFile()
+ */
function streamFile( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
function streamFile( array $params ) {
$status = Status::newGood();
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::getLocalReference()
+ */
function getLocalReference( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
function getLocalReference( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::getLocalCopy()
+ */
function getLocalCopy( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
function getLocalCopy( array $params ) {
# Hit all backends in case of failed operations (out of sync)
foreach ( $this->backends as $backend ) {
+ /**
+ * @see FileBackendBase::getFileList()
+ */
function getFileList( array $params ) {
foreach ( $this->backends as $index => $backend ) {
# Get results from the first backend
function getFileList( array $params ) {
foreach ( $this->backends as $index => $backend ) {
# Get results from the first backend