generated from Nodarx/template
feat: track cache changes with sequence numbers and tombstones
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -10,6 +10,8 @@ declare(strict_types=1);
|
||||
namespace KTXM\ProviderImap\Stores;
|
||||
|
||||
use KTXC\Db\DataStore;
|
||||
use MongoDB\Operation\FindOneAndUpdate;
|
||||
use RuntimeException;
|
||||
use KTXM\ProviderImap\Providers\CollectionResource;
|
||||
|
||||
/**
|
||||
@@ -29,6 +31,7 @@ class MailboxStore
|
||||
'uidNext' => null,
|
||||
'highestModSeq' => null,
|
||||
'changeSeq' => 0,
|
||||
'purgedSeq' => 0,
|
||||
'harmonizedAt' => null,
|
||||
'harmonizationComplete' => false,
|
||||
];
|
||||
@@ -112,7 +115,7 @@ class MailboxStore
|
||||
/**
|
||||
* Harmonization state of a mailbox; defaults when the mailbox is not cached.
|
||||
*
|
||||
* @return array{uidValidity: ?int, uidNext: ?int, highestModSeq: ?int, changeSeq: int, harmonizedAt: ?int, harmonizationComplete: bool}
|
||||
* @return array{uidValidity: ?int, uidNext: ?int, highestModSeq: ?int, changeSeq: int, purgedSeq: int, harmonizedAt: ?int, harmonizationComplete: bool}
|
||||
*/
|
||||
public function state(string $serviceId, string $name): array
|
||||
{
|
||||
@@ -137,6 +140,34 @@ class MailboxStore
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserve a range of change sequence numbers for a mailbox.
|
||||
*
|
||||
* Atomically advances the mailbox's changeSeq by $count and returns the first
|
||||
* number of the reserved range (range = first .. first + count - 1).
|
||||
*
|
||||
* @throws RuntimeException when the mailbox is not cached
|
||||
*/
|
||||
public function reserveSequence(string $serviceId, string $name, int $count = 1): int
|
||||
{
|
||||
$count = max(1, $count);
|
||||
|
||||
$document = $this->dataStore->selectCollection(self::COLLECTION_NAME)->getMongoCollection()->findOneAndUpdate(
|
||||
['sid' => $serviceId, 'name' => $name],
|
||||
['$inc' => ['changeSeq' => $count]],
|
||||
[
|
||||
'projection' => ['changeSeq' => 1],
|
||||
'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
|
||||
],
|
||||
);
|
||||
|
||||
if ($document === null) {
|
||||
throw new RuntimeException("Mailbox is not cached: {$name}");
|
||||
}
|
||||
|
||||
return (int) ((array) $document)['changeSeq'] - $count + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the harmonization lock of a mailbox when it is free or expired.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user