Skip to content

Commit a59129f

Browse files
committed
TASK: Optimise redis content cache reader
Only upload script once and reuse script and redis instance
1 parent 3816e27 commit a59129f

File tree

1 file changed

+62
-24
lines changed

1 file changed

+62
-24
lines changed

Classes/NodeRendering/Infrastructure/RedisContentCacheReader.php

+62-24
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,11 @@ class RedisContentCacheReader
3838
*/
3939
protected $applicationIdentifier;
4040

41-
protected $redis;
41+
protected ?string $scriptSha1 = null;
42+
protected ?\Redis $redis = null;
4243

4344
public function tryToExtractRenderingForEnumeratedNodeFromContentCache(DocumentNodeCacheKey $documentNodeCacheKey
4445
): RenderedDocumentFromContentCache {
45-
$maxNestLevel = ContentCache::MAXIMUM_NESTING_LEVEL;
46-
$contentCacheStartToken = ContentCache::CACHE_SEGMENT_START_TOKEN;
47-
$contentCacheEndToken = ContentCache::CACHE_SEGMENT_END_TOKEN;
48-
$contentCacheMarker = ContentCache::CACHE_SEGMENT_MARKER;
4946
/**
5047
* @see AbstractBackend::setCache()
5148
*/
@@ -60,8 +57,66 @@ public function tryToExtractRenderingForEnumeratedNodeFromContentCache(DocumentN
6057
);
6158
}
6259
$documentNodeCacheValues = DocumentNodeCacheValues::fromJsonString($serializedCacheValues);
60+
$res = $this->executeRedisCall([$documentNodeCacheValues->getRootIdentifier(), $identifierPrefix]);
61+
[$content, $error] = $res;
6362

64-
$script = "
63+
if (strlen($error) > 0) {
64+
return RenderedDocumentFromContentCache::createIncomplete($error);
65+
}
66+
return RenderedDocumentFromContentCache::createWithFullContent($content, $documentNodeCacheValues);
67+
}
68+
69+
protected function executeRedisCall(array $params): array
70+
{
71+
$redis = $this->getRedis();
72+
73+
$this->prepareRedisScript();
74+
try {
75+
// starting with Lua 7, eval_ro can be used.
76+
$res = $redis->evalSha($this->scriptSha1, $params);
77+
78+
$error = $redis->getLastError();
79+
if ($error !== null) {
80+
throw new \RuntimeException('Redis error: ' . $error);
81+
}
82+
} catch (\Exception $e) {
83+
throw new \RuntimeException('Redis script execution error: ' . $e->getMessage());
84+
}
85+
86+
if (!is_array($res) || count($res) !== 2) {
87+
throw new \RuntimeException('Result is no array of length 2, but: ' . count($res));
88+
}
89+
90+
return $res;
91+
}
92+
93+
protected function prepareRedisScript(): void
94+
{
95+
$redis = $this->getRedis();
96+
97+
try {
98+
// Load script into redis if it is not already loaded
99+
$scriptExists = false;
100+
if ($this->scriptSha1) {
101+
$scriptExists = $redis->script('exists', $this->scriptSha1)[0] ?? false;
102+
}
103+
if (!$scriptExists) {
104+
$script = $this->buildRedisScript();
105+
$this->scriptSha1 = $redis->script('load', $script);
106+
}
107+
} catch (\RedisException $e) {
108+
throw new \RuntimeException('Redis Error: ' . $e->getMessage());
109+
}
110+
}
111+
112+
protected function buildRedisScript(): string
113+
{
114+
$maxNestLevel = ContentCache::MAXIMUM_NESTING_LEVEL;
115+
$contentCacheStartToken = ContentCache::CACHE_SEGMENT_START_TOKEN;
116+
$contentCacheEndToken = ContentCache::CACHE_SEGMENT_END_TOKEN;
117+
$contentCacheMarker = ContentCache::CACHE_SEGMENT_MARKER;
118+
119+
return "
65120
local rootIdentifier = ARGV[1]
66121
local identifierPrefix = ARGV[2]
67122
@@ -110,29 +165,12 @@ public function tryToExtractRenderingForEnumeratedNodeFromContentCache(DocumentN
110165
111166
return {content, error}
112167
";
113-
// starting with Lua 7, eval_ro can be used.
114-
$res = $redis->eval($script, [$documentNodeCacheValues->getRootIdentifier(), $identifierPrefix], 0);
115-
$error = $redis->getLastError();
116-
if ($error !== null) {
117-
throw new \RuntimeException('Redis Error: ' . $error);
118-
}
119-
120-
if (count($res) !== 2) {
121-
throw new \RuntimeException('Result is no array of length 2, but: ' . count($res));
122-
}
123-
$content = $res[0];
124-
$error = $res[1];
125-
126-
if (strlen($error) > 0) {
127-
return RenderedDocumentFromContentCache::createIncomplete($error);
128-
}
129-
return RenderedDocumentFromContentCache::createWithFullContent($content, $documentNodeCacheValues);
130168
}
131169

132170
/**
133171
* @throws UnknownPackageException
134172
*/
135-
protected function getRedis()
173+
protected function getRedis(): \Redis
136174
{
137175
if ($this->redis) {
138176
return $this->redis;

0 commit comments

Comments
 (0)