|
3 | 3 | namespace Drupal\graphql\Plugin\GraphQL\DataProducer; |
4 | 4 |
|
5 | 5 | use Drupal\Core\Cache\Cache; |
| 6 | +use Drupal\Core\Cache\CacheableDependencyInterface; |
6 | 7 | use Drupal\Core\Cache\CacheableMetadata; |
7 | 8 | use Drupal\Core\Cache\CacheBackendInterface; |
8 | 9 | use Drupal\Core\Cache\Context\CacheContextsManager; |
@@ -226,10 +227,6 @@ protected function resolveCached(DataProducerPluginCachingInterface $plugin, Res |
226 | 227 |
|
227 | 228 | $output = $this->resolveUncached($plugin, $context, $field); |
228 | 229 | return DeferredUtility::applyFinally($output, function ($value) use ($context, $field, $prefix) { |
229 | | - if ($field->getCacheMaxAge() === 0) { |
230 | | - return; |
231 | | - } |
232 | | - |
233 | 230 | $this->cacheWrite($prefix, $value, $field); |
234 | 231 | }); |
235 | 232 | } |
@@ -276,16 +273,32 @@ protected function cacheRead($prefix) { |
276 | 273 | * @param \Drupal\graphql\GraphQL\Execution\FieldContext $field |
277 | 274 | */ |
278 | 275 | protected function cacheWrite($prefix, $value, FieldContext $field) { |
279 | | - $expire = $this->maxAgeToExpire($field->getCacheMaxAge()); |
280 | | - $tags = $field->getCacheTags(); |
281 | | - $tokens = $field->getCacheContexts(); |
282 | | - |
283 | | - $keys = !empty($tokens) ? $this->contextsManager->convertTokensToKeys($tokens)->getKeys() : []; |
284 | | - $keys = serialize($keys); |
| 276 | + // Bail out early if the field context is already uncacheable. |
| 277 | + if ($field->getCacheMaxAge() === 0) { |
| 278 | + return; |
| 279 | + } |
285 | 280 |
|
286 | 281 | $metadata = new CacheableMetadata(); |
287 | 282 | $metadata->addCacheableDependency($field); |
288 | 283 |
|
| 284 | + // Do not add the cache contexts from the result value because they are not |
| 285 | + // known at fetch time and would render the written cache unusable. |
| 286 | + if ($value instanceof CacheableDependencyInterface) { |
| 287 | + $metadata->addCacheTags($value->getCacheTags()); |
| 288 | + $metadata->mergeCacheMaxAge($value->getCacheMaxAge()); |
| 289 | + } |
| 290 | + |
| 291 | + if ($metadata->getCacheMaxAge() === 0) { |
| 292 | + return; |
| 293 | + } |
| 294 | + |
| 295 | + $expire = $this->maxAgeToExpire($metadata->getCacheMaxAge()); |
| 296 | + $tags = $metadata->getCacheTags(); |
| 297 | + $tokens = $metadata->getCacheContexts(); |
| 298 | + |
| 299 | + $keys = !empty($tokens) ? $this->contextsManager->convertTokensToKeys($tokens)->getKeys() : []; |
| 300 | + $keys = serialize($keys); |
| 301 | + |
289 | 302 | $this->cacheBackend->setMultiple([ |
290 | 303 | "$prefix:context" => [ |
291 | 304 | 'data' => $tokens, |
|
0 commit comments