Merge pull request #56407 from nextcloud/backport/56255/stable32

[stable32] make failed availability check apply in the same request
pull/56411/head
Robin Appelman 2025-11-12 22:49:23 +07:00 committed by GitHub
commit a784bdadcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 6 deletions

@ -126,7 +126,7 @@ class Storage {
}
/**
* @return array [ available, last_checked ]
* @return array{available: bool, last_checked: int}
*/
public function getAvailability() {
if ($row = self::getStorageById($this->storageId)) {

@ -711,7 +711,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
}
/**
* @return array [ available, last_checked ]
* @return array{available: bool, last_checked: int}
*/
public function getAvailability(): array {
return $this->getStorageCache()->getAvailability();

@ -22,6 +22,7 @@ class Availability extends Wrapper {
/** @var IConfig */
protected $config;
protected ?bool $available = null;
public function __construct(array $parameters) {
$this->config = $parameters['config'] ?? \OCP\Server::get(IConfig::class);
@ -54,11 +55,14 @@ class Availability extends Wrapper {
}
private function isAvailable(): bool {
$availability = $this->getAvailability();
if (self::shouldRecheck($availability)) {
return $this->updateAvailability();
if (is_null($this->available)) {
$availability = $this->getAvailability();
if (self::shouldRecheck($availability)) {
return $this->updateAvailability();
}
$this->available = $availability['available'];
}
return $availability['available'];
return $this->available;
}
/**
@ -257,6 +261,7 @@ class Availability extends Wrapper {
self::RECHECK_TTL_SEC
);
}
$this->available = false;
$this->getStorageCache()->setAvailability(false, $delay);
if ($e !== null) {
throw $e;

@ -155,4 +155,30 @@ class AvailabilityTest extends \Test\TestCase {
$this->wrapper->mkdir('foobar');
}
public function testUnavailableMultiple(): void {
$this->storage->expects($this->once())
->method('getAvailability')
->willReturn(['available' => true, 'last_checked' => 0]);
$this->storage->expects($this->never())
->method('test');
$this->storage
->expects($this->once()) // load-bearing `once`
->method('mkdir')
->willThrowException(new StorageNotAvailableException());
try {
$this->wrapper->mkdir('foobar');
$this->fail();
} catch (StorageNotAvailableException) {
}
$this->storage->expects($this->never())->method('file_exists');
try {
$this->wrapper->mkdir('foobar');
$this->fail();
} catch (StorageNotAvailableException) {
}
}
}