Skip to content

Commit

Permalink
Merge pull request #53 from nlx-lars/feature/shorten-tags
Browse files Browse the repository at this point in the history
FEATURE: Add option to use short md5 for cache tags
  • Loading branch information
paxuclus authored Dec 7, 2020
2 parents 6e6ca76 + b88d843 commit b431dbb
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 14 deletions.
10 changes: 9 additions & 1 deletion Classes/Http/CacheControlHeaderComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use MOC\Varnish\Aspects\ContentCacheAspect;
use MOC\Varnish\Cache\MetadataAwareStringFrontend;
use MOC\Varnish\Service\CacheTagService;
use MOC\Varnish\Service\TokenStorage;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
Expand Down Expand Up @@ -49,6 +50,12 @@ class CacheControlHeaderComponent implements ComponentInterface
*/
protected $propertyMapper;

/**
* @var CacheTagService
* @Flow\Inject
*/
protected $cacheTagService;

/**
* @var MetadataAwareStringFrontend
*/
Expand Down Expand Up @@ -109,7 +116,8 @@ public function handle(ComponentContext $componentContext)
list($tags, $cacheLifetime) = $this->getCacheTagsAndLifetime();

if (count($tags) > 0) {
$modifiedResponse = $modifiedResponse->withHeader('X-Cache-Tags', implode(',', $tags));
$shortenedTags = $this->cacheTagService->shortenTags($tags);
$modifiedResponse = $modifiedResponse->withHeader('X-Cache-Tags', implode(',', $shortenedTags));
}

$modifiedResponse = $modifiedResponse->withHeader('X-Site', $this->tokenStorage->getToken());
Expand Down
59 changes: 59 additions & 0 deletions Classes/Service/CacheTagService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);

namespace MOC\Varnish\Service;

use Neos\Flow\Annotations as Flow;

/**
* @Flow\Scope("singleton")
*/
class CacheTagService
{

/**
* @var int
* @Flow\InjectConfiguration(path="cacheHeaders")
*/
protected $cacheHeaderConfiguration;

/**
* @see \Neos\Fusion\Core\Cache\ContentCache::sanitizeTags()
*
* @param array $tags
* @return array
*/
public function sanitizeTags(array $tags): array
{
return array_map(function (string $tag) {
return strtr($tag, '.:', '_-');
}, $tags);
}

/**
* Generate short md5 for cache tags if enabled
*
* See these two configuration options:
* * MOC.Varnish.cacheHeaders.shortenCacheTags
* * MOC.Varnish.cacheHeaders.cacheTagLength
*
* @param array $tags
* @return array
*/
public function shortenTags(array $tags = []): array
{
if (!$this->shouldShortenTags()) {
return $tags;
}

return array_map(function (string $tag) {
return substr(md5($tag), 0, (int)$this->cacheHeaderConfiguration['cacheTagLength'] ?? 8);
}, $tags);
}

protected function shouldShortenTags(): bool
{
return (bool)$this->cacheHeaderConfiguration['shortenCacheTags'] ?? false;
}

}
17 changes: 13 additions & 4 deletions Classes/Service/ContentCacheFlusherService.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ protected function generateCacheTags(NodeInterface $node): void
if ($nodeInWorkspace === null) {
break;
}
$tagName = 'DescendantOf_' . $workspaceHash . '_' . $nodeInWorkspace->getIdentifier();
$this->tagsToFlush[$tagName] = sprintf('which were tagged with "%s" because node "%s" has changed.', $tagName, $node->getPath());
$this->generateCacheTagsForDescendantOf($workspaceHash . '_' . $nodeInWorkspace->getIdentifier());
}
}

Expand All @@ -133,8 +132,17 @@ protected function generateCacheTags(NodeInterface $node): void
*/
protected function generateCacheTagsForNodeIdentifier(string $cacheIdentifier): void
{
$this->tagsToFlush['Node_' . $cacheIdentifier] = sprintf('which were tagged with "Node_%s" because that identifier has changed.', $cacheIdentifier);
$tagName = 'Node_' . $cacheIdentifier;
$this->tagsToFlush[$tagName] = sprintf('which were tagged with "%s" because node identifier "%s" has changed.', $tagName, $cacheIdentifier);
// Note, as we don't have a node here we cannot go up the structure.
$this->generateCacheTagsForDescendantOf($cacheIdentifier);
}

/**
* @param string $cacheIdentifier
*/
protected function generateCacheTagsForDescendantOf(string $cacheIdentifier): void
{
$tagName = 'DescendantOf_' . $cacheIdentifier;
$this->tagsToFlush[$tagName] = sprintf('which were tagged with "%s" because node "%s" has changed.', $tagName, $cacheIdentifier);
}
Expand All @@ -154,7 +162,8 @@ protected function generateCacheTagsForNodeType(string $nodeTypeName, string $re
$nodeTypePrefix = rtrim($nodeTypePrefix, '_') . '_';
}
foreach ($nodeTypesToFlush as $nodeTypeNameToFlush) {
$this->tagsToFlush['NodeType_' . $nodeTypePrefix . $nodeTypeNameToFlush] = sprintf('which were tagged with "NodeType_%s" because node "%s" has changed and was of type "%s".', $nodeTypeNameToFlush, ($referenceNodeIdentifier ? $referenceNodeIdentifier : ''), $nodeTypeName);
$tagName = 'NodeType_' . $nodeTypePrefix . $nodeTypeNameToFlush;
$this->tagsToFlush[$tagName] = sprintf('which were tagged with "%s" because node "%s" has changed and was of type "%s".', $tagName, $referenceNodeIdentifier ?: '', $nodeTypeName);
}
}

Expand Down
15 changes: 8 additions & 7 deletions Classes/Service/VarnishBanService.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ class VarnishBanService
*/
protected $tokenStorage;

/**
* @Flow\Inject
* @var CacheTagService
*/
protected $cacheTagService;

/**
* @var array
*/
Expand Down Expand Up @@ -109,13 +115,8 @@ public function banByTags(array $tags, $domains = null): void
$tags = array_diff($tags, $this->settings['ignoredCacheTags']);
}

/**
* Sanitize tags
* @see \Neos\Fusion\Core\Cache\ContentCache
*/
foreach ($tags as $key => $tag) {
$tags[$key] = strtr($tag, '.:', '_-');
}
$tags = $this->cacheTagService->sanitizeTags($tags);
$tags = $this->cacheTagService->shortenTags($tags);

$this->varnishProxyClient->forHosts(...$this->domainsToArray($domains));
$this->cacheInvalidator->invalidateTags($tags);
Expand Down
8 changes: 6 additions & 2 deletions Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ MOC:
varnishUrl: 'http://127.0.0.1'
# Cache header sending configuration
cacheHeaders:
# Default and maximum TTL in seconds
defaultSharedMaximumAge: null
# Disable sending headers (useful for staging environments)
disabled: false
# Default and maximum TTL in seconds
defaultSharedMaximumAge: null
# Enable shortening of Cache Tags (useful when response headers get too large)
shortenCacheTags: false
# Length of the short md5 if shortenCacheTags is enabled
cacheTagLength: 8

# Maximum length of header in bytes for requests to varnish. Used when banning. Large requests will be split across multiple smaller ones
maximumHeaderLength: 7500
Expand Down
4 changes: 4 additions & 0 deletions Documentation/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ There are several configuration options can/needs to be set:
If not set, the Varnish configuration needs to cache by default since no ``Cache-Control`` header will be sent
- Disable sending of cache headers - can be used to disable Varnish on staging environment e.g.
``MOC.Varnish.cacheHeaders.disabled`` accepts boolean value (defaults to ``FALSE``)
- Since 4.1.0: The generated Cache Tags can be shortened using this option
``MOC.Varnish.cacheHeaders.shortenCacheTags`` accepts boolean value (defaults to ``FALSE``)
- Since 4.1.0: If shortenCacheTags is enabled, this option controls the length of the used md5 for tags
``MOC.Varnish.cacheHeaders.cacheTagLength`` accepts integer value (defaults to ``8``)
- Reverse lookup port can be set to allow debugging in the backend module if the web server port is not ``80``
``MOC.Varnish.reverseLookupPort`` accepts integer (defaults to ``NULL``)
- Ignored cache tags can be used to ignore certain cache tags from being cleared at all (useful for optimizing)
Expand Down

0 comments on commit b431dbb

Please sign in to comment.