Skip to content

Commit

Permalink
Theorhetical, better caching.
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-vessey committed Mar 25, 2024
1 parent 42ee442 commit b1e8b33
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 10 deletions.
7 changes: 7 additions & 0 deletions embargo.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@ services:
- '@service_container'
tags:
- { name: 'event_subscriber' }
cache_context.ip.embargo_range:
class: Drupal\embargo\Cache\Context\IpRangeCacheContext
arguments:
- '@request_stack'
- '@entity_type.manager'
tags:
- { name: cache.context }
81 changes: 81 additions & 0 deletions src/Cache/Context/IpRangeCacheContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Drupal\embargo\Cache\Context;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
* Applicable embargo IP range cache context info.
*/
class IpRangeCacheContext implements CacheContextInterface {

/**
* Memoized ranges.
*
* @var \Drupal\embargo\IpRangeInterface[]
*/
protected array $ranges;

/**
* Constructor.
*/
public function __construct(
protected RequestStack $requestStack,
protected EntityTypeManagerInterface $entityTypeManager,
) {
// No-op, other than stashing properties.
}

/**
* {@inheritDoc}
*/
public static function getLabel() {
return \t('Embargo, Applicable IP Ranges');
}

/**
* {@inheritDoc}
*/
public function getContext() {
$range_keys = array_keys($this->getRanges());
sort($range_keys, SORT_NUMERIC);
return implode(',', $range_keys);
}

/**
* {@inheritDoc}
*/
public function getCacheableMetadata() {
$cache_meta = new CacheableMetadata();

foreach ($this->getRanges() as $range) {
$cache_meta->addCacheableDependency($range);
}

return $cache_meta;
}

/**
* Get any IP range entities associated with the current IP address.
*
* @return \Drupal\embargo\IpRangeInterface[]
* Any relevant IP range entities.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getRanges() : array {
if (!isset($this->ranges)) {
/** @var \Drupal\embargo\IpRangeStorageInterface $embargo_ip_range_storage */
$embargo_ip_range_storage = $this->entityTypeManager->getStorage('embargo_ip_range');
$this->ranges = $embargo_ip_range_storage->getApplicableIpRanges($this->requestStack->getCurrentRequest()
->getClientIp());
}

return $this->ranges;
}

}
34 changes: 25 additions & 9 deletions src/Entity/Embargo.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,33 +378,49 @@ public function setEmbargoedNode(NodeInterface $node): EmbargoInterface {
}

/**
* The maximum age for which this object may be cached.
*
* @return int
* The maximum time in seconds that this object may be cached.
* {@inheritDoc}
*/
public function getCacheMaxAge() {
$max_age = parent::getCacheMaxAge();

$now = time();
// Invalidate cache after a scheduled embargo expires.
if ($this->getExpirationType() === static::EXPIRATION_TYPE_SCHEDULED && !$this->expiresBefore($now)) {
return $this->getExpirationDate()->getTimestamp() - $now;
$max_age = Cache::mergeMaxAges($max_age, $this->getExpirationDate()->getTimestamp() - $now);
}
// Other properties of the embargo are not time dependent.
return parent::getCacheMaxAge();

return $max_age;
}

/**
* {@inheritdoc}
*/
public function getCacheTags() {
$tags = parent::getCacheTags();
$tags[] = "node:{$this->getEmbargoedNode()->id()}";
$tags = Cache::mergeTags(parent::getCacheTags(), $this->getEmbargoedNode()->getCacheTags());

if ($this->getExemptIps()) {
$tags = Cache::mergeTags($tags, $this->getExemptIps()->getCacheTags());
}
return $tags;
}

/**
* {@inheritDoc}
*/
public function getCacheContexts() {
$contexts = Cache::mergeContexts(
parent::getCacheContexts(),
$this->getEmbargoedNode()->getCacheContexts(),
[$this->getExemptUsers() ? 'user' : 'user.permissions'],
);

if ($this->getExemptIps()) {
$contexts = Cache::mergeContexts($contexts, $this->getExemptIps()->getCacheContexts());
}

return $contexts;
}

/**
* {@inheritdoc}
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Entity/IpRange.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Drupal\embargo\Entity;

use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityStorageInterface;
Expand Down Expand Up @@ -239,4 +240,13 @@ public static function isValidCidr(string $cidr): bool {
return FALSE;
}

/**
* {@inheritDoc}
*/
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), [
'ip.embargo_range',
]);
}

}
2 changes: 1 addition & 1 deletion src/Plugin/search_api/processor/EmbargoProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ protected function addEmbargoFilters(string $datasource_id, QueryInterface $quer
$or_group->addCondition($field->getFieldIdentifier(), $ipRange->id());
$query->addCacheableDependency($ipRange);
}
$query->addCacheContexts(['ip']);
$query->addCacheContexts(['ip.embargo_range']);
}

return (count($or_group->getConditions()) > 0) ? $or_group : NULL;
Expand Down

0 comments on commit b1e8b33

Please sign in to comment.