generated from Nodarx/template
feat: serve message fetches from the cache
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -173,14 +173,33 @@ class CachedService extends ServiceBase
|
||||
|
||||
public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array
|
||||
{
|
||||
// served from the cache in 5.2c
|
||||
return $this->live()->entityFetchBulk(...$identifiers);
|
||||
return iterator_to_array($this->entityFetchStream(...$identifiers), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch messages from the cache; messages that are not cached are fetched from the
|
||||
* server and cached, mailboxes never harmonized are read from the server.
|
||||
*/
|
||||
public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator
|
||||
{
|
||||
// served from the cache in 5.2c
|
||||
return $this->live()->entityFetchStream(...$identifiers);
|
||||
$byMailbox = [];
|
||||
foreach ($identifiers as $identifier) {
|
||||
if ($identifier->provider() !== $this->provider() || (string) $identifier->service() !== $this->serviceId()) {
|
||||
throw new \InvalidArgumentException('Entity identifier does not belong to this service: ' . $identifier);
|
||||
}
|
||||
$byMailbox[(string) $identifier->collection()][] = (int) $identifier->entity();
|
||||
}
|
||||
|
||||
foreach ($byMailbox as $mailbox => $uids) {
|
||||
$uidValidity = $this->mailboxStore->state($this->serviceId(), (string) $mailbox)['uidValidity'];
|
||||
$entities = $uidValidity === null
|
||||
? $this->liveMail()->entityFetch((string) $mailbox, ...$uids)
|
||||
: $this->hydrate((string) $mailbox, (int) $uidValidity, $uids);
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
yield $entity->urn() => $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,6 +308,9 @@ class CachedService extends ServiceBase
|
||||
$missing[] = $uid;
|
||||
continue;
|
||||
}
|
||||
if ($entity->getProperties()->getIncompleteSections() !== []) {
|
||||
$this->completeSections($mailbox, $uidValidity, $entity);
|
||||
}
|
||||
$entities[$uid] = $entity;
|
||||
}
|
||||
|
||||
@@ -307,6 +329,31 @@ class CachedService extends ServiceBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the full content of sections cut off at ingest and store the completed message.
|
||||
*
|
||||
* Content is immutable, so the meta document and change sequence are untouched. A
|
||||
* failure leaves the cut off text in place; it is tried again on the next read.
|
||||
*/
|
||||
private function completeSections(string $mailbox, int $uidValidity, EntityResource $entity): void
|
||||
{
|
||||
$properties = $entity->getProperties();
|
||||
$uid = (int) $entity->identifier();
|
||||
|
||||
try {
|
||||
$sections = $this->liveMail()->messageSections($mailbox, $uid, ...$properties->getIncompleteSections());
|
||||
if ($sections === []) {
|
||||
return;
|
||||
}
|
||||
foreach ($sections as $partId => $content) {
|
||||
$properties->completeSection((string) $partId, $content);
|
||||
}
|
||||
$this->fileStore->write($this->tenantId(), $this->serviceId(), $mailbox, $uidValidity, $uid, $entity->toCacheContent());
|
||||
} catch (\Throwable) {
|
||||
// keep the cut off text; retried on the next read
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity from its meta document and message.json; null when the content is missing or outdated.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user