@@ -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