Skip to content

Commit 655f123

Browse files
authored
Merge pull request #28 from CandoImage/feat/optimize-cache-handling-to-reduce-impact-on-response-times
feat: Optimize cache handling to reduce impact on response times
2 parents ba26a14 + d0007bf commit 655f123

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

src/EventListener/CacheListener.php

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Pimcore\Model\Document\Link;
2424
use Pimcore\Model\Document\PageSnippet;
2525
use Pimcore\Model\Element\AbstractElement;
26+
use Symfony\Component\EventDispatcher\GenericEvent;
2627

2728
class CacheListener
2829
{
@@ -58,18 +59,13 @@ public static function addCachingItem(
5859
self::$cachingItems = new \SplObjectStorage();
5960
}
6061

61-
// Load object to get cache tags.
62-
$object = Concrete::getById($objectId);
63-
if ($object) {
64-
self::$cachingItems[$operation] = self::$cachingItems[$operation] ?? [];
65-
$cacheTags = ['datahub-cache'] + (self::getObjectCacheTags($object) ?? []);
66-
self::$cachingItems[$operation] += [$cid => [
67-
'path' => $path,
68-
'tags' => $cacheTags,
69-
'indexKey' => $indexKey,
70-
'lifetime' => $lifetime,
71-
]];
72-
}
62+
self::$cachingItems[$operation] = self::$cachingItems[$operation] ?? [];
63+
self::$cachingItems[$operation] += [$cid => [
64+
'objectId' => $objectId,
65+
'path' => $path,
66+
'indexKey' => $indexKey,
67+
'lifetime' => $lifetime,
68+
]];
7369
}
7470

7571
public static function clearCachingItems(OperationParams $operation = null): void
@@ -100,35 +96,72 @@ public static function arrayGetNestedValue(array &$array, array $parents, &$key_
10096
return $ref;
10197
}
10298

99+
/**
100+
* Add the cache item meta-data before saving the cache items.
101+
*
102+
* Uses shutdown because at this point the response should be already
103+
* delivered and any further processing shouldn't affect reponse times.
104+
*
105+
* @param \Symfony\Component\EventDispatcher\GenericEvent $event
106+
*
107+
* @return void
108+
*/
109+
public function onPimcoreShutdown(GenericEvent $event): void
110+
{
111+
foreach (self::$cachingItems ?? [] as $operation) {
112+
// Find items declared for caching in result set and store them in cache.
113+
foreach (self::$cachingItems[$operation] as $cid => $item) {
114+
// Extract the related cache tags.
115+
$cacheTags = [];
116+
$object = Concrete::getById($item['objectId']);
117+
if (!empty($object)) {
118+
$cacheTags = ['datahub-cache'] + (self::getObjectCacheTags($object) ?? []);
119+
}
120+
// Not sure why force is necessary.
121+
Cache::save(
122+
$item['data'],
123+
$cid,
124+
$cacheTags,
125+
$item['lifetime'] ?? null,
126+
0,
127+
true
128+
);
129+
}
130+
}
131+
}
132+
133+
/**
134+
* Adds the actual data to the for caching prepared cache items.
135+
*
136+
* Do NOT save yet - wait for that till shutdown to ensure response is
137+
* out before triggering any further processing.
138+
*
139+
*
140+
* @param \Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\CacheItemEvent $event
141+
*
142+
* @return void
143+
*/
103144
public function onCacheItemEvent(CacheItemEvent $event): void
104145
{
105146
$operation = $event->getOperation();
106-
107147
if (isset(self::$cachingItems[$operation])) {
108148
$result = $event->getResult();
109149
$data = $result->data;
110-
111150
// Find items declared for caching in result set and store them in cache.
112-
foreach (self::$cachingItems[$operation] as $cid => $item) {
151+
$cachedItems = self::$cachingItems[$operation];
152+
foreach ($cachedItems as $cid => $item) {
113153
// replace the "delta" placeholder with the effective index to extract data
114154
$path = $item['path'];
115155
if ($index = array_search('delta', $path, true)) {
116156
$path[$index] = $item['indexKey'];
117157
}
118158
// Extract the cacheable portion from the result.
119159
$value = self::arrayGetNestedValue($data, $path);
120-
$cacheTags = $item['tags'] ?? [];
121-
Cache::save(
122-
$value,
123-
$cid,
124-
$cacheTags,
125-
$item['lifetime'] ?? null,
126-
0,
127-
true
128-
);
160+
$item['data'] = $value;
161+
$cachedItems[$cid] = $item;
162+
self::$cachingItems->offsetSet($operation, $cachedItems);
129163
}
130164
}
131-
self::clearCachingItems($operation);
132165
}
133166

134167
/**

src/Resources/config/eventlistener.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ services:
1212
Pimcore\Bundle\DataHubBundle\EventListener\CacheListener:
1313
tags:
1414
- { name: kernel.event_listener, event: pimcore.datahub.graphql.cache.item, method: onCacheItemEvent }
15+
- { name: kernel.event_listener, event: pimcore.system.shutdown, method: onPimcoreShutdown }
1516

1617
Pimcore\Bundle\DataHubBundle\EventListener\AdminListener:
1718
bind:

0 commit comments

Comments
 (0)