Retry putContent operation if locked (#694)

Retry putContent operation if locked
This commit is contained in:
Julius Härtl 2019-11-14 22:32:48 +01:00 коммит произвёл GitHub
Родитель 3e383dd77c f84c7adc36
Коммит 49887218a9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 40 добавлений и 2 удалений

Просмотреть файл

@ -34,6 +34,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\GenericFileException;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
@ -46,6 +47,7 @@ use OCP\IURLGenerator;
use OCP\AppFramework\Http\StreamResponse;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Lock\LockedException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
@ -437,7 +439,14 @@ class WopiController extends Controller {
$this->userSession->setUser($editor);
}
$file->putContent($content);
try {
$this->retryOperation(function () use ($file, $content){
return $file->putContent($content);
});
} catch (LockedException $e) {
$this->logger->logException($e);
return new JSONResponse(['message' => 'File locked'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
if ($isPutRelative) {
// generate a token for the new file (the user still has to be
@ -567,7 +576,13 @@ class WopiController extends Controller {
$this->userSession->setUser($editor);
}
$file->putContent($content);
try {
$this->retryOperation(function () use ($file, $content){
return $file->putContent($content);
});
} catch (LockedException $e) {
return new JSONResponse(['message' => 'File locked'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
// generate a token for the new file (the user still has to be
// logged in)
@ -583,6 +598,29 @@ class WopiController extends Controller {
}
}
/**
* Retry operation if a LockedException occurred
* Other exceptions will still be thrown
* @param callable $operation
* @throws LockedException
* @throws GenericFileException
*/
private function retryOperation(callable $operation) {
for ($i = 0; $i < 5; $i++) {
try {
if ($operation() !== false) {
return;
}
} catch (LockedException $e) {
if ($i === 4) {
throw $e;
}
usleep(500000);
}
}
throw new GenericFileException('Operation failed after multiple retries');
}
/**
* @param Wopi $wopi
* @return File|Folder|Node|null