Index: trunk/phase3/includes/filerepo/backend/FileBackendMultiWrite.php |
— | — | @@ -10,6 +10,8 @@ |
11 | 11 | * registered to this proxy backend and it will act as a single backend. |
12 | 12 | * Use this when all access to those backends is through this proxy backend. |
13 | 13 | * At least one of the backends must be declared the "master" backend. |
| 14 | + * |
| 15 | + * Only use this class when transitioning from one storage system to another. |
14 | 16 | * |
15 | 17 | * The order that the backends are defined sets the priority of which |
16 | 18 | * backend is read from or written to first. Functions like fileExists() |
— | — | @@ -62,7 +64,10 @@ |
63 | 65 | } |
64 | 66 | } |
65 | 67 | |
66 | | - final public function doOperations( array $ops, array $opts = array() ) { |
| 68 | + /** |
| 69 | + * @see FileBackendBase::doOperationsInternal() |
| 70 | + */ |
| 71 | + final protected function doOperationsInternal( array $ops, array $opts ) { |
67 | 72 | $status = Status::newGood(); |
68 | 73 | |
69 | 74 | $performOps = array(); // list of FileOp objects |
— | — | @@ -145,6 +150,9 @@ |
146 | 151 | } |
147 | 152 | } |
148 | 153 | |
| 154 | + /** |
| 155 | + * @see FileBackendBase::prepare() |
| 156 | + */ |
149 | 157 | function prepare( array $params ) { |
150 | 158 | $status = Status::newGood(); |
151 | 159 | foreach ( $this->backends as $backend ) { |
— | — | @@ -154,6 +162,9 @@ |
155 | 163 | return $status; |
156 | 164 | } |
157 | 165 | |
| 166 | + /** |
| 167 | + * @see FileBackendBase::secure() |
| 168 | + */ |
158 | 169 | function secure( array $params ) { |
159 | 170 | $status = Status::newGood(); |
160 | 171 | foreach ( $this->backends as $backend ) { |
— | — | @@ -163,6 +174,9 @@ |
164 | 175 | return $status; |
165 | 176 | } |
166 | 177 | |
| 178 | + /** |
| 179 | + * @see FileBackendBase::clean() |
| 180 | + */ |
167 | 181 | function clean( array $params ) { |
168 | 182 | $status = Status::newGood(); |
169 | 183 | foreach ( $this->backends as $backend ) { |
— | — | @@ -172,6 +186,9 @@ |
173 | 187 | return $status; |
174 | 188 | } |
175 | 189 | |
| 190 | + /** |
| 191 | + * @see FileBackendBase::fileExists() |
| 192 | + */ |
176 | 193 | function fileExists( array $params ) { |
177 | 194 | # Hit all backends in case of failed operations (out of sync) |
178 | 195 | foreach ( $this->backends as $backend ) { |
— | — | @@ -183,12 +200,18 @@ |
184 | 201 | return false; |
185 | 202 | } |
186 | 203 | |
| 204 | + /** |
| 205 | + * @see FileBackendBase::getFileTimestamp() |
| 206 | + */ |
187 | 207 | function getFileTimestamp( array $params ) { |
188 | 208 | // Skip non-master for consistent timestamps |
189 | 209 | $realParams = $this->substOpPaths( $params, $backend ); |
190 | 210 | return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams ); |
191 | 211 | } |
192 | 212 | |
| 213 | + /** |
| 214 | + * @see FileBackendBase::getFileSha1Base36() |
| 215 | + */ |
193 | 216 | function getFileSha1Base36( array $params ) { |
194 | 217 | # Hit all backends in case of failed operations (out of sync) |
195 | 218 | foreach ( $this->backends as $backend ) { |
— | — | @@ -201,6 +224,9 @@ |
202 | 225 | return false; |
203 | 226 | } |
204 | 227 | |
| 228 | + /** |
| 229 | + * @see FileBackendBase::getFileProps() |
| 230 | + */ |
205 | 231 | function getFileProps( array $params ) { |
206 | 232 | # Hit all backends in case of failed operations (out of sync) |
207 | 233 | foreach ( $this->backends as $backend ) { |
— | — | @@ -213,6 +239,9 @@ |
214 | 240 | return null; |
215 | 241 | } |
216 | 242 | |
| 243 | + /** |
| 244 | + * @see FileBackendBase::streamFile() |
| 245 | + */ |
217 | 246 | function streamFile( array $params ) { |
218 | 247 | $status = Status::newGood(); |
219 | 248 | foreach ( $this->backends as $backend ) { |
— | — | @@ -234,6 +263,9 @@ |
235 | 264 | return $status; |
236 | 265 | } |
237 | 266 | |
| 267 | + /** |
| 268 | + * @see FileBackendBase::getLocalReference() |
| 269 | + */ |
238 | 270 | function getLocalReference( array $params ) { |
239 | 271 | # Hit all backends in case of failed operations (out of sync) |
240 | 272 | foreach ( $this->backends as $backend ) { |
— | — | @@ -246,6 +278,9 @@ |
247 | 279 | return null; |
248 | 280 | } |
249 | 281 | |
| 282 | + /** |
| 283 | + * @see FileBackendBase::getLocalCopy() |
| 284 | + */ |
250 | 285 | function getLocalCopy( array $params ) { |
251 | 286 | # Hit all backends in case of failed operations (out of sync) |
252 | 287 | foreach ( $this->backends as $backend ) { |
— | — | @@ -258,6 +293,9 @@ |
259 | 294 | return null; |
260 | 295 | } |
261 | 296 | |
| 297 | + /** |
| 298 | + * @see FileBackendBase::getFileList() |
| 299 | + */ |
262 | 300 | function getFileList( array $params ) { |
263 | 301 | foreach ( $this->backends as $index => $backend ) { |
264 | 302 | # Get results from the first backend |
Index: trunk/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -128,11 +128,15 @@ |
129 | 129 | * exists at the destination that has the same |
130 | 130 | * contents as the new contents to be written there. |
131 | 131 | * |
132 | | - * $opts is an associative of options, including: |
| 132 | + * $opts is an associative of boolean flags, including: |
| 133 | + * 'ignoreErrors' : Errors that would normally cause a rollback do not. |
| 134 | + * The remaining operations are still attempted if any fail. |
133 | 135 | * 'nonLocking' : No locks are acquired for the operations. |
134 | 136 | * This can increase performance for non-critical writes. |
135 | | - * 'ignoreErrors' : Serious errors that would normally cause a rollback |
136 | | - * do not. The remaining operations are still attempted. |
| 137 | + * This has no effect unless the 'ignoreErrors' flag is set. |
| 138 | + * 'allowStale' : Don't require the latest available data. |
| 139 | + * This can increase performance for non-critical writes. |
| 140 | + * This has no effect unless the 'ignoreErrors' flag is set. |
137 | 141 | * |
138 | 142 | * Return value: |
139 | 143 | * This returns a Status, which contains all warnings and fatals that occured |
— | — | @@ -144,9 +148,20 @@ |
145 | 149 | * @param $opts Array Batch operation options |
146 | 150 | * @return Status |
147 | 151 | */ |
148 | | - abstract public function doOperations( array $ops, array $opts = array() ); |
| 152 | + final public function doOperations( array $ops, array $opts = array() ) { |
| 153 | + if ( empty( $opts['ignoreErrors'] ) ) { // sanity |
| 154 | + unset( $opts['nonLocking'] ); |
| 155 | + unset( $opts['allowStale'] ); |
| 156 | + } |
| 157 | + return $this->doOperationsInternal( $ops, $opts ); |
| 158 | + } |
149 | 159 | |
150 | 160 | /** |
| 161 | + * @see FileBackendBase::doOperations() |
| 162 | + */ |
| 163 | + abstract protected function doOperationsInternal( array $ops, array $opts ); |
| 164 | + |
| 165 | + /** |
151 | 166 | * Same as doOperations() except it takes a single operation. |
152 | 167 | * If you are doing a batch of operations that should either |
153 | 168 | * all succeed or all fail, then use that function instead. |
— | — | @@ -296,7 +311,8 @@ |
297 | 312 | * Check if a file exists at a storage path in the backend. |
298 | 313 | * |
299 | 314 | * $params include: |
300 | | - * src : source storage path |
| 315 | + * src : source storage path |
| 316 | + * latest : use the latest available data |
301 | 317 | * |
302 | 318 | * @param $params Array |
303 | 319 | * @return bool |
— | — | @@ -307,7 +323,8 @@ |
308 | 324 | * Get a SHA-1 hash of the file at a storage path in the backend. |
309 | 325 | * |
310 | 326 | * $params include: |
311 | | - * src : source storage path |
| 327 | + * src : source storage path |
| 328 | + * latest : use the latest available data |
312 | 329 | * |
313 | 330 | * @param $params Array |
314 | 331 | * @return string|false Hash string or false on failure |
— | — | @@ -318,7 +335,8 @@ |
319 | 336 | * Get the last-modified timestamp of the file at a storage path. |
320 | 337 | * |
321 | 338 | * $params include: |
322 | | - * src : source storage path |
| 339 | + * src : source storage path |
| 340 | + * latest : use the latest available data |
323 | 341 | * |
324 | 342 | * @param $params Array |
325 | 343 | * @return string|false TS_MW timestamp or false on failure |
— | — | @@ -330,7 +348,8 @@ |
331 | 349 | * Returns FSFile::placeholderProps() on failure. |
332 | 350 | * |
333 | 351 | * $params include: |
334 | | - * src : source storage path |
| 352 | + * src : source storage path |
| 353 | + * latest : use the latest available data |
335 | 354 | * |
336 | 355 | * @param $params Array |
337 | 356 | * @return Array |
— | — | @@ -346,6 +365,7 @@ |
347 | 366 | * $params include: |
348 | 367 | * src : source storage path |
349 | 368 | * headers : additional HTTP headers to send on success |
| 369 | + * latest : use the latest available data |
350 | 370 | * |
351 | 371 | * @param $params Array |
352 | 372 | * @return Status |
— | — | @@ -353,20 +373,6 @@ |
354 | 374 | abstract public function streamFile( array $params ); |
355 | 375 | |
356 | 376 | /** |
357 | | - * Get an iterator to list out all object files under a storage directory. |
358 | | - * If the directory is of the form "mwstore://container", then all items in |
359 | | - * the container should be listed. If of the form "mwstore://container/dir", |
360 | | - * then all items under that container directory should be listed. |
361 | | - * Results should be storage paths relative to the given directory. |
362 | | - * |
363 | | - * $params include: |
364 | | - * dir : storage path directory |
365 | | - * |
366 | | - * @return Traversable|Array|null Returns null on failure |
367 | | - */ |
368 | | - abstract public function getFileList( array $params ); |
369 | | - |
370 | | - /** |
371 | 377 | * Returns a file system file, identical to the file at a storage path. |
372 | 378 | * The file returned is either: |
373 | 379 | * a) A local copy of the file at a storage path in the backend. |
— | — | @@ -379,7 +385,8 @@ |
380 | 386 | * In that later case, there are copies of the file that must stay in sync. |
381 | 387 | * |
382 | 388 | * $params include: |
383 | | - * src : source storage path |
| 389 | + * src : source storage path |
| 390 | + * latest : use the latest available data |
384 | 391 | * |
385 | 392 | * @param $params Array |
386 | 393 | * @return FSFile|null Returns null on failure |
— | — | @@ -392,7 +399,8 @@ |
393 | 400 | * Temporary files may be purged when the file object falls out of scope. |
394 | 401 | * |
395 | 402 | * $params include: |
396 | | - * src : source storage path |
| 403 | + * src : source storage path |
| 404 | + * latest : use the latest available data |
397 | 405 | * |
398 | 406 | * @param $params Array |
399 | 407 | * @return TempFSFile|null Returns null on failure |
— | — | @@ -400,6 +408,20 @@ |
401 | 409 | abstract public function getLocalCopy( array $params ); |
402 | 410 | |
403 | 411 | /** |
| 412 | + * Get an iterator to list out all object files under a storage directory. |
| 413 | + * If the directory is of the form "mwstore://container", then all items in |
| 414 | + * the container should be listed. If of the form "mwstore://container/dir", |
| 415 | + * then all items under that container directory should be listed. |
| 416 | + * Results should be storage paths relative to the given directory. |
| 417 | + * |
| 418 | + * $params include: |
| 419 | + * dir : storage path directory |
| 420 | + * |
| 421 | + * @return Traversable|Array|null Returns null on failure |
| 422 | + */ |
| 423 | + abstract public function getFileList( array $params ); |
| 424 | + |
| 425 | + /** |
404 | 426 | * Lock the files at the given storage paths in the backend. |
405 | 427 | * This will either lock all the files or none (on failure). |
406 | 428 | * |
— | — | @@ -700,6 +722,8 @@ |
701 | 723 | |
702 | 724 | /** |
703 | 725 | * Return a list of FileOp objects from a list of operations. |
| 726 | + * Do not call this function from places outside FileBackend. |
| 727 | + * |
704 | 728 | * The result must have the same number of items as the input. |
705 | 729 | * An exception is thrown if an unsupported operation is requested. |
706 | 730 | * |
— | — | @@ -729,14 +753,15 @@ |
730 | 754 | } |
731 | 755 | |
732 | 756 | /** |
733 | | - * @see FileBackendBase::doOperations() |
| 757 | + * @see FileBackendBase::doOperationsInternal() |
734 | 758 | */ |
735 | | - final public function doOperations( array $ops, array $opts = array() ) { |
| 759 | + protected function doOperationsInternal( array $ops, array $opts ) { |
736 | 760 | $status = Status::newGood(); |
737 | 761 | |
738 | 762 | // Build up a list of FileOps... |
739 | 763 | $performOps = $this->getOperations( $ops ); |
740 | 764 | |
| 765 | + // Acquire any locks as needed... |
741 | 766 | if ( empty( $opts['nonLocking'] ) ) { |
742 | 767 | // Build up a list of files to lock... |
743 | 768 | $filesLockEx = $filesLockSh = array(); |