22
33namespace Drupal \graphql \GraphQL \Execution ;
44
5- use Drupal \Core \Cache \CacheableDependencyInterface ;
5+ use Drupal \Core \Cache \Cache ;
66use Drupal \Core \Cache \CacheableMetadata ;
77use Drupal \Core \Cache \CacheBackendInterface ;
88use Drupal \Core \Cache \Context \CacheContextsManager ;
9- use Drupal \Core \Session \AccountProxyInterface ;
109use Drupal \graphql \Plugin \SchemaPluginManager ;
11- use Drupal \graphql \GraphQL \QueryProvider \QueryProviderInterface ;
1210use Drupal \graphql \GraphQL \Cache \CacheableRequestError ;
1311use GraphQL \Error \Error ;
1412use GraphQL \Error \FormattedError ;
2624use GraphQL \Utils \AST ;
2725use GraphQL \Utils \TypeInfo ;
2826use GraphQL \Utils \Utils ;
29- use GraphQL \Validator \DocumentValidator ;
3027use GraphQL \Validator \Rules \AbstractValidationRule ;
3128use GraphQL \Validator \ValidationContext ;
29+ use Symfony \Component \HttpFoundation \RequestStack ;
3230
3331// TODO: Refactor this and clean it up.
3432class QueryProcessor {
@@ -54,6 +52,13 @@ class QueryProcessor {
5452 */
5553 protected $ contextsManager ;
5654
55+ /**
56+ * The request stack.
57+ *
58+ * @var \Symfony\Component\HttpFoundation\RequestStack
59+ */
60+ protected $ requestStack ;
61+
5762 /**
5863 * Processor constructor.
5964 *
@@ -63,15 +68,19 @@ class QueryProcessor {
6368 * The schema plugin manager.
6469 * @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
6570 * The cache backend for caching query results.
71+ * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
72+ * The request stack.
6673 */
6774 public function __construct (
6875 CacheContextsManager $ contextsManager ,
6976 SchemaPluginManager $ pluginManager ,
70- CacheBackendInterface $ cacheBackend
77+ CacheBackendInterface $ cacheBackend ,
78+ RequestStack $ requestStack
7179 ) {
7280 $ this ->contextsManager = $ contextsManager ;
7381 $ this ->pluginManager = $ pluginManager ;
7482 $ this ->cacheBackend = $ cacheBackend ;
83+ $ this ->requestStack = $ requestStack ;
7584 }
7685
7786 /**
@@ -223,24 +232,27 @@ protected function executeOperation(PromiseAdapter $adapter, ServerConfig $confi
223232 * @return \GraphQL\Executor\Promise\Promise|mixed
224233 */
225234 protected function executeCacheableOperation (PromiseAdapter $ adapter , ServerConfig $ config , OperationParams $ params , DocumentNode $ document ) {
226- $ contextCacheId = 'ccid: ' . $ this ->cacheIdentifier ($ params , $ document, new CacheableMetadata () );
227-
228- if (! $ config -> getDebug () && ( $ contextCache = $ this -> cacheBackend -> get ( $ contextCacheId )) && $ contexts = $ contextCache ->data ) {
229- $ cacheId = 'cid: ' . $ this ->cacheIdentifier ($ params , $ document , ( new CacheableMetadata ())-> addCacheContexts ( $ contexts) );
230- if (( $ cache = $ this ->cacheBackend ->get ($ cacheId )) && $ result = $ cache -> data ) {
231- return $ adapter ->createFulfilled ($ result );
235+ $ contextCacheId = 'ccid: ' . $ this ->cacheIdentifier ($ params , $ document );
236+ if (! $ config -> getDebug () && $ contextCache = $ this -> cacheBackend -> get ( $ contextCacheId )) {
237+ $ contexts = $ contextCache ->data ?: [];
238+ $ cid = 'cid: ' . $ this ->cacheIdentifier ($ params , $ document , $ contexts );
239+ if ($ cache = $ this ->cacheBackend ->get ($ cid ) ) {
240+ return $ adapter ->createFulfilled ($ cache -> data );
232241 }
233242 }
234243
235244 $ result = $ this ->doExecuteOperation ($ adapter , $ config , $ params , $ document );
236-
237245 return $ result ->then (function (QueryResult $ result ) use ($ contextCacheId , $ params , $ document ) {
238246 // Write this query into the cache if it is cacheable.
239247 if ($ result ->getCacheMaxAge () !== 0 ) {
240- $ cacheId = 'cid: ' . $ this ->cacheIdentifier ($ params , $ document , (new CacheableMetadata ())->addCacheContexts ($ result ->getCacheContexts ()));
241- $ this ->cacheBackend ->set ($ contextCacheId , $ result ->getCacheContexts (), $ result ->getCacheMaxAge (), $ result ->getCacheTags ());
242- $ this ->cacheBackend ->set ($ cacheId , $ result , $ result ->getCacheMaxAge (), $ result ->getCacheTags ());
248+ $ contexts = $ result ->getCacheContexts ();
249+ $ expire = $ this ->maxAgeToExpire ($ result ->getCacheMaxAge ());
250+ $ tags = $ result ->getCacheTags ();
251+ $ cid = 'cid: ' . $ this ->cacheIdentifier ($ params , $ document , $ contexts );
252+ $ this ->cacheBackend ->set ($ contextCacheId , $ contexts , $ expire , $ tags );
253+ $ this ->cacheBackend ->set ($ cid , $ result , $ expire , $ tags );
243254 }
255+
244256 return $ result ;
245257 });
246258 }
@@ -290,7 +302,6 @@ protected function doExecuteOperation(PromiseAdapter $adapter, ServerConfig $con
290302 );
291303
292304 return $ promise ->then (function (ExecutionResult $ result ) use ($ context ) {
293-
294305 $ metadata = (new CacheableMetadata ())
295306 ->addCacheContexts ($ this ->filterCacheContexts ($ context ->getCacheContexts ()))
296307 ->addCacheTags ($ context ->getCacheTags ())
@@ -451,13 +462,13 @@ protected function sanitizeRecursive(array $item) {
451462 /**
452463 * @param \GraphQL\Server\OperationParams $params
453464 * @param \GraphQL\Language\AST\DocumentNode $document
454- * @param \Drupal\Core\Cache\CacheableMetadata $metadata
465+ * @param array $contexts
455466 *
456467 * @return string
457468 */
458- protected function cacheIdentifier (OperationParams $ params , DocumentNode $ document , CacheableMetadata $ metadata ) {
469+ protected function cacheIdentifier (OperationParams $ params , DocumentNode $ document , array $ contexts = [] ) {
459470 // Ignore language contexts since they are handled by graphql internally.
460- $ contexts = $ this ->filterCacheContexts ($ metadata -> getCacheContexts () );
471+ $ contexts = $ this ->filterCacheContexts ($ contexts );
461472 $ keys = $ this ->contextsManager ->convertTokensToKeys ($ contexts )->getKeys ();
462473
463474 // Sorting the variables will cause fewer cache vectors.
@@ -489,4 +500,19 @@ protected function filterCacheContexts(array $contexts) {
489500 return strpos ($ context , 'languages: ' ) !== 0 ;
490501 });
491502 }
503+
504+ /**
505+ * Maps a cache max age value to an "expire" value for the Cache API.
506+ *
507+ * @param int $maxAge
508+ *
509+ * @return int
510+ * A corresponding "expire" value.
511+ *
512+ * @see \Drupal\Core\Cache\CacheBackendInterface::set()
513+ */
514+ protected function maxAgeToExpire ($ maxAge ) {
515+ $ time = $ this ->requestStack ->getMasterRequest ()->server ->get ('REQUEST_TIME ' );
516+ return ($ maxAge === Cache::PERMANENT ) ? Cache::PERMANENT : (int ) $ time + $ maxAge ;
517+ }
492518}
0 commit comments