Skip to content
Snippets Groups Projects

Issue #3172194: Move the logic to a real purger for...

Open Jose Jiménez requested to merge issue/varnish_purge-3172194:3172194 into 8.x-2.x
13 files
+ 806
427
Compare changes
  • Side-by-side
  • Inline
Files
13
<?php
/**
* @file
* Contains varnish_focal_point_purge.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
use Drupal\Core\Entity\EntityInterface;
use GuzzleHttp\Client;
use Drupal\file\FileInterface;
use Drupal\varnish_purger\Plugin\Purge\Purger\VarnishPurger;
/**
* Implements hook_help().
*/
function varnish_focal_point_purge_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.varnish_focal_point_purge':
$output = '';
$output .= '<h2>' . t('About') . '</h2>';
$output .= '<p>' . t('Purge focal point entities after they are updated') . '</p>';
$output .= '<p>' . t('You need to setup Varnish to listen to the request method URIBAN. Example:') . '</p>';
$output .= '<pre><code>if (req.method == "URIBAN") {<br />';
$output .= ' ban("req.http.host == " + req.http.host + " && req.url == " + req.url);<br />';
$output .= ' # Throw a synthetic page so the request won\'t go to the backend.<br />';
$output .= ' return (synth(200, "Ban added."));<br />';
$output .= '}</code></pre>';
return $output;
default:
}
}
/**
* Implements hook_entity_update().
*/
function varnish_focal_point_purge_entity_update(EntityInterface $entity) {
if ($entity->bundle() !== 'focal_point') {
return;
}
// Get the name(s) of the varnish purge configs, they get random suffix.
// This is ugly, should be done better I guess.
$query = \Drupal::database()->select('config', 'c');
$query->fields('c', ['name']);
$query->condition('c.name', $query->escapeLike('varnish_purger.settings') . '%', 'LIKE');
$varnish_purgers = $query->execute()->fetchAllKeyed(0, 0);
// Set the array to use for varnish purgers.
$purgers = [];
foreach ($varnish_purgers as $key => $value) {
$config_purge = \Drupal::config($key);
$purgers[$key]['hostname'] = $config_purge->get('hostname');
$purgers[$key]['port'] = $config_purge->get('port');
}
if (empty($varnish_purgers)) {
return;
}
$file = File::load($entity->entity_id->value);
if (!($file instanceof FileInterface)) {
return;
}
// TODO: Consider are we not doing duplicated work related to varnish_image purge...
// Do the actual purging...
/* @var $client Client */
$client = \Drupal::service('http_client');
// Generator for purge requests to be sent out.
$requests = function() use ($client, $file) {
$styles = ImageStyle::loadMultiple();
/* @var $style Drupal\image\Entity\ImageStyle; */
foreach ($styles as $style) {
$url = $style->buildUrl($file->getFileUri());
yield function () use ($client, $url) {
return $client->requestAsync('URIBAN', $url)->then(
function() {
},
function($reason) use ($url) {
$message = $reason instanceof \Exception ? $reason->getMessage() : (string) $reason;
$logger = \Drupal::logger('varnish_focal_point_purge');
$logger->error("URL not purged $url {$message}");
}
);
};
}
};
// Prepare a POOL that will make the requests with a given concurrency.
// TODO: Have the concurrency exposed as configuration somewhere.
$concurrency = VarnishPurger::VARNISH_PURGE_CONCURRENCY;
(new \GuzzleHttp\Pool($client, $requests(), ['concurrency' => $concurrency]))
->promise()
->wait();
}
Loading