Skip to content

Commit

Permalink
Merge pull request #4819 from nextcloud/fix/database-is-locked
Browse files Browse the repository at this point in the history
Fix database locks
  • Loading branch information
ChristophWurst authored Mar 25, 2021
2 parents 7bc1cb1 + 00ea427 commit 3575d85
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 9 deletions.
21 changes: 17 additions & 4 deletions lib/Db/Mailbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class Mailbox extends Entity implements JsonSerializable {
protected $specialUse;
protected $syncInBackground;

/**
* @var int
* Lock timeout for sync (5 minutes)
*/
public const LOCK_TIMEOUT = 300;

public function __construct() {
$this->addType('accountId', 'integer');
$this->addType('messages', 'integer');
Expand Down Expand Up @@ -119,10 +125,17 @@ public function isCached(): bool {
&& $this->getSyncVanishedToken() !== null;
}

public function hasLocks(): bool {
return $this->getSyncNewLock() !== null
|| $this->getSyncChangedLock() !== null
|| $this->getSyncVanishedLock() !== null;
public function hasLocks(int $now): bool {
if ($this->getSyncNewLock() !== null || $this->getSyncNewLock() > ($now - self::LOCK_TIMEOUT)) {
return true;
}
if ($this->getSyncChangedLock() !== null || $this->getSyncChangedLock() > ($now - self::LOCK_TIMEOUT)) {
return true;
}
if ($this->getSyncVanishedLock() !== null || $this->getSyncVanishedLock() > ($now - self::LOCK_TIMEOUT)) {
return true;
}
return false;
}

public function jsonSerialize() {
Expand Down
2 changes: 1 addition & 1 deletion lib/Db/MailboxMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private function lockForSync(Mailbox $mailbox, string $attr, ?int $lock): int {
$now = $this->timeFactory->getTime();

if ($lock !== null
&& $lock > ($now - 5 * 60)) {
&& $lock > ($now - Mailbox::LOCK_TIMEOUT)) {
// Another process is syncing
throw MailboxLockedException::from($mailbox);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Db/TagMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public function getAllTagsForMessages(array $messages): array {
foreach ($queryResult as $qr) {
$result[] = $qr['imap_message_id'];
$result[$qr['imap_message_id']][] = $this->getTag((int)$qr['tag_id']);
};
}
return $result;
}

Expand Down
10 changes: 8 additions & 2 deletions lib/Service/Search/MailSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use OCA\Mail\IMAP\PreviewEnhancer;
use OCA\Mail\IMAP\Search\Provider as ImapSearchProvider;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IUser;

class MailSearch implements IMailSearch {
Expand All @@ -58,16 +59,21 @@ class MailSearch implements IMailSearch {
/** @var PreviewEnhancer */
private $previewEnhancer;

/** @var ITimeFactory */
private $timeFactory;

public function __construct(FilterStringParser $filterStringParser,
MailboxMapper $mailboxMapper,
ImapSearchProvider $imapSearchProvider,
MessageMapper $messageMapper,
PreviewEnhancer $previewEnhancer) {
PreviewEnhancer $previewEnhancer,
ITimeFactory $timeFactory) {
$this->filterStringParser = $filterStringParser;
$this->mailboxMapper = $mailboxMapper;
$this->imapSearchProvider = $imapSearchProvider;
$this->messageMapper = $messageMapper;
$this->previewEnhancer = $previewEnhancer;
$this->timeFactory = $timeFactory;
}

public function findMessage(Account $account,
Expand Down Expand Up @@ -101,7 +107,7 @@ public function findMessages(Account $account,
?string $filter,
?int $cursor,
?int $limit): array {
if ($mailbox->hasLocks()) {
if ($mailbox->hasLocks($this->timeFactory->getTime())) {
throw MailboxLockedException::from($mailbox);
}
if (!$mailbox->isCached()) {
Expand Down
8 changes: 7 additions & 1 deletion tests/Unit/Service/Search/MailSearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use OCA\Mail\Service\Search\Flag;
use OCA\Mail\Service\Search\MailSearch;
use OCA\Mail\Service\Search\SearchQuery;
use OCP\AppFramework\Utility\ITimeFactory;
use PHPUnit\Framework\MockObject\MockObject;

class MailSearchTest extends TestCase {
Expand All @@ -61,6 +62,9 @@ class MailSearchTest extends TestCase {
/** @var MessageMapper|MockObject */
private $messageMapper;

/** @var ITimeFactory|MockObject */
private $timeFactory;

protected function setUp(): void {
parent::setUp();

Expand All @@ -69,13 +73,15 @@ protected function setUp(): void {
$this->imapSearchProvider = $this->createMock(Provider::class);
$this->messageMapper = $this->createMock(MessageMapper::class);
$this->previewEnhancer = $this->createMock(PreviewEnhancer::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);

$this->search = new MailSearch(
$this->filterStringParser,
$this->mailboxMapper,
$this->imapSearchProvider,
$this->messageMapper,
$this->previewEnhancer
$this->previewEnhancer,
$this->timeFactory
);
}

Expand Down

0 comments on commit 3575d85

Please sign in to comment.