Skip to content

Commit c6ff3e8

Browse files
authored
Merge pull request #2 from integer-net/add-config-values
Add config values
2 parents 1765ed6 + cea089b commit c6ff3e8

File tree

9 files changed

+251
-17
lines changed

9 files changed

+251
-17
lines changed

src/Console/Command/PurgeAsyncTagsCommand.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
namespace IntegerNet\AsyncVarnish\Console\Command;
55

66
use IntegerNet\AsyncVarnish\Model\PurgeAsyncCache as Purger;
7+
use Magento\Framework\App\State;
78
use Symfony\Component\Console\Input\InputInterface;
89
use Symfony\Component\Console\Output\OutputInterface;
910

1011
class PurgeAsyncTagsCommand extends \Symfony\Component\Console\Command\Command
1112
{
1213
/**
13-
* @var \Magento\Framework\App\State
14+
* @var State
1415
*/
1516
private $appState;
1617

@@ -20,7 +21,7 @@ class PurgeAsyncTagsCommand extends \Symfony\Component\Console\Command\Command
2021
private $purger;
2122

2223
public function __construct(
23-
\Magento\Framework\App\State\Proxy $appState,
24+
State $appState,
2425
Purger $purger,
2526
?string $name = null
2627
) {
@@ -32,16 +33,16 @@ public function __construct(
3233
/**
3334
* {@inheritdoc}
3435
*/
35-
protected function configure() //phpcs:ignore
36+
protected function configure()
3637
{
3738
$this->setName('integernet:asyncvarnish:purge')
38-
->setDescription('Purges Varnish Tags ');
39+
->setDescription('Purges Varnish Tags currently stored in database table');
3940
}
4041

4142
/**
4243
* {@inheritdoc}
4344
*/
44-
protected function execute(InputInterface $input, OutputInterface $output) //phpcs:ignore
45+
protected function execute(InputInterface $input, OutputInterface $output)
4546
{
4647
try {
4748
$this->appState->setAreaCode('adminhtml');

src/Model/PurgeAsyncCache.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,67 @@
55

66
use Magento\CacheInvalidate\Model\PurgeCache as PurgeCache;
77
use IntegerNet\AsyncVarnish\Model\TagRepository as TagRepository;
8+
use Magento\Framework\App\Config\ScopeConfigInterface;
89

910
class PurgeAsyncCache
1011
{
11-
/**
12-
* Size of the chunks we're sending to Varnish
13-
*/
14-
const CHUNK_SIZE = 100;
12+
const VARNISH_PURGE_TAG_GLUE = "|";
13+
const MAX_HEADER_LENGTH_CONFIG_PATH = 'system/full_page_cache/async_varnish/varnish_max_header_length';
1514

1615
/**
17-
* @var \Magento\CacheInvalidate\Model\PurgeCache
16+
* @var PurgeCache
1817
*/
1918
private $purgeCache;
2019

2120
/**
22-
* @var \IntegerNet\AsyncVarnish\Model\TagRepository
21+
* @var TagRepository
2322
*/
2423
private $tagRepository;
2524

25+
/**
26+
* @var ScopeConfigInterface
27+
*/
28+
private $scopeConfig;
29+
2630
public function __construct(
2731
PurgeCache $purgeCache,
32+
ScopeConfigInterface $scopeConfig,
2833
TagRepository $tagRepository
2934
) {
3035
$this->purgeCache = $purgeCache;
36+
$this->scopeConfig = $scopeConfig;
3137
$this->tagRepository = $tagRepository;
3238
}
3339

40+
private function getMaxHeaderLengthFromConfig()
41+
{
42+
return $this->scopeConfig->getValue(self::MAX_HEADER_LENGTH_CONFIG_PATH);
43+
}
44+
3445
/**
3546
* @throws \Zend_Db_Statement_Exception
3647
* @throws \Exception
3748
*/
3849
public function run():int
3950
{
4051
$tags = $this->tagRepository->getAll();
41-
52+
$maxHeaderLength = $this->getMaxHeaderLengthFromConfig();
4253
if (!empty($tags)) {
43-
$tagChunks = array_chunk($tags, self::CHUNK_SIZE, true);
54+
$tagChunks = [];
55+
$index = 0;
56+
foreach ($tags as $tag) {
57+
$nextChunkString = (isset($tagChunks[$index])
58+
? $tagChunks[$index] . self::VARNISH_PURGE_TAG_GLUE
59+
: '') . $tag;
60+
if (strlen($nextChunkString) <= $maxHeaderLength) {
61+
$tagChunks[$index] = $nextChunkString;
62+
} else {
63+
$index ++;
64+
$tagChunks[$index] = $tag;
65+
}
66+
}
4467
foreach ($tagChunks as $tagChunk) {
45-
$this->purgeCache->sendPurgeRequest(implode('|', array_unique($tagChunk)));
68+
$this->purgeCache->sendPurgeRequest($tagChunk);
4669
}
4770
}
4871

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace IntegerNet\AsyncVarnish\Model\System\Config\Backend;
5+
6+
use Magento\Framework\App\Cache\TypeListInterface;
7+
use Magento\Framework\App\Config\Value;
8+
use Magento\Framework\App\ObjectManager;
9+
use Magento\Framework\Data\Collection\AbstractDb;
10+
use Magento\Framework\Escaper;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Model\Context;
14+
use Magento\Framework\Model\ResourceModel\AbstractResource;
15+
use Magento\Framework\Registry;
16+
17+
/**
18+
* Backend model for processing Varnish Fetch Tag Limit settings
19+
*
20+
* Class HeaderLength
21+
*/
22+
class FetchTagLimit extends Value
23+
{
24+
/**
25+
* @var Escaper
26+
*/
27+
private $escaper;
28+
29+
/**
30+
* Ttl constructor.
31+
* @param Context $context
32+
* @param Registry $registry
33+
* @param ScopeConfigInterface $config
34+
* @param TypeListInterface $cacheTypeList
35+
* @param Escaper $escaper
36+
* @param AbstractResource|null $resource
37+
* @param AbstractDb|null $resourceCollection
38+
* @param array $data
39+
*/
40+
public function __construct(
41+
Context $context,
42+
Registry $registry,
43+
ScopeConfigInterface $config,
44+
TypeListInterface $cacheTypeList,
45+
Escaper $escaper,
46+
?AbstractResource $resource = null,
47+
?AbstractDb $resourceCollection = null,
48+
array $data = []
49+
) {
50+
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
51+
$this->escaper = $escaper;
52+
}
53+
54+
/**
55+
* Throw exception if HeaderLength data is invalid or empty
56+
*
57+
* @return $this
58+
* @throws LocalizedException
59+
*/
60+
public function beforeSave()
61+
{
62+
$value = $this->getValue();
63+
if ($value < 0 || !preg_match('/^[0-9]+$/', $value)) {
64+
throw new LocalizedException(
65+
__(
66+
'Fetch tag limit value "%1" is not valid. Please use only numbers equal or greater than 0.',
67+
$this->escaper->escapeHtml($value)
68+
)
69+
);
70+
}
71+
return $this;
72+
}
73+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace IntegerNet\AsyncVarnish\Model\System\Config\Backend;
5+
6+
use Magento\Framework\App\Cache\TypeListInterface;
7+
use Magento\Framework\App\Config\Value;
8+
use Magento\Framework\App\ObjectManager;
9+
use Magento\Framework\Data\Collection\AbstractDb;
10+
use Magento\Framework\Escaper;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Model\Context;
14+
use Magento\Framework\Model\ResourceModel\AbstractResource;
15+
use Magento\Framework\Registry;
16+
17+
/**
18+
* Backend model for processing Varnish Max header length settings
19+
*
20+
* Class HeaderLength
21+
*/
22+
class HeaderLength extends Value
23+
{
24+
/**
25+
* @var Escaper
26+
*/
27+
private $escaper;
28+
29+
/**
30+
* Ttl constructor.
31+
* @param Context $context
32+
* @param Registry $registry
33+
* @param ScopeConfigInterface $config
34+
* @param TypeListInterface $cacheTypeList
35+
* @param Escaper $escaper
36+
* @param AbstractResource|null $resource
37+
* @param AbstractDb|null $resourceCollection
38+
* @param array $data
39+
*/
40+
public function __construct(
41+
Context $context,
42+
Registry $registry,
43+
ScopeConfigInterface $config,
44+
TypeListInterface $cacheTypeList,
45+
Escaper $escaper,
46+
?AbstractResource $resource = null,
47+
?AbstractDb $resourceCollection = null,
48+
array $data = []
49+
) {
50+
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
51+
$this->escaper = $escaper;
52+
}
53+
54+
/**
55+
* Throw exception if HeaderLength data is invalid or lower than 40 bytes
56+
*
57+
* @return $this
58+
* @throws LocalizedException
59+
*/
60+
public function beforeSave()
61+
{
62+
$value = $this->getValue();
63+
if ($value < 40 || !preg_match('/^[0-9]+$/', $value)) {
64+
throw new LocalizedException(
65+
__(
66+
'Header Length value "%1" is not valid. Please use only numbers equal or greater than 40.',
67+
$this->escaper->escapeHtml($value)
68+
)
69+
);
70+
}
71+
return $this;
72+
}
73+
}

src/Model/TagRepository.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use Magento\Framework\App\ResourceConnection;
77
use IntegerNet\AsyncVarnish\Model\ResourceModel\Tag as TagResource;
8+
use Magento\Framework\App\Config\ScopeConfigInterface;
89

910
class TagRepository
1011
{
@@ -16,7 +17,7 @@ class TagRepository
1617
/**
1718
* Limits the amount of tags being fetched from database
1819
*/
19-
const TAG_LIMIT = 1000000;
20+
const FETCH_TAG_LIMIT_CONFIG_PATH = 'system/full_page_cache/async_varnish/varnish_fetch_tag_limit';
2021

2122
private $lastUsedId;
2223

@@ -35,16 +36,25 @@ class TagRepository
3536
*/
3637
private $tagResource;
3738

39+
private $scopeConfig;
40+
3841
/**
3942
* @param \Magento\Framework\App\ResourceConnection $resource
4043
*/
4144
public function __construct(
4245
ResourceConnection $resource,
43-
TagResource $tagResource
46+
TagResource $tagResource,
47+
ScopeConfigInterface $scopeConfig
4448
) {
4549
$this->connection = $resource->getConnection();
4650
$this->resource = $resource;
4751
$this->tagResource = $tagResource;
52+
$this->scopeConfig = $scopeConfig;
53+
}
54+
55+
private function getTagFetchLimit()
56+
{
57+
return $this->scopeConfig->getValue(self::FETCH_TAG_LIMIT_CONFIG_PATH);
4858
}
4959

5060
/**
@@ -102,8 +112,9 @@ public function getAll()
102112
$tags = [];
103113

104114
$tagResource = $this->tagResource;
115+
$tagFetchLimit = $this->getTagFetchLimit();
105116

106-
$maxIdResult = $tagResource->getMaxTagId(self::TAG_LIMIT);
117+
$maxIdResult = $tagResource->getMaxTagId($tagFetchLimit);
107118

108119
if (empty($maxIdResult)) {
109120
return $tags;

src/Observer/InvalidateVarnishAsyncObserver.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class InvalidateVarnishAsyncObserver implements ObserverInterface
3232
* @var \IntegerNet\AsyncVarnish\Model\TagRepository
3333
*/
3434
private $tagRepository;
35+
3536
/**
3637
* @param \Magento\PageCache\Model\Config $config
3738
* @param \Magento\CacheInvalidate\Model\PurgeCache $purgeCache

src/etc/adminhtml/system.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
3+
<system>
4+
<section id="system">
5+
<group id="full_page_cache">
6+
<group id="async_varnish" translate="label" showInDefault="1" showInWebsite="0" showInStore="0"
7+
sortOrder="610">
8+
<label>Async Varnish Configuration</label>
9+
<field id="varnish_max_header_length" type="text" translate="label comment" sortOrder="100"
10+
showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1">
11+
<label>Varnish max allowed header length.</label>
12+
<backend_model>IntegerNet\AsyncVarnish\Model\System\Config\Backend\HeaderLength</backend_model>
13+
<comment>Depends on varnish 'http_req_hdr_len' setting. Default value is 8000b (8k), minimum
14+
40b. See https://varnish-cache.org/docs/4.1/reference/varnishd.html#http-req-hdr-len.</comment>
15+
<depends>
16+
<field id="caching_application">1</field>
17+
</depends>
18+
</field>
19+
<field id="varnish_fetch_tag_limit" type="text" translate="label comment" sortOrder="110"
20+
showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1">
21+
<label>Varnish fetch tag limit.</label>
22+
<backend_model>IntegerNet\AsyncVarnish\Model\System\Config\Backend\FetchTagLimit</backend_model>
23+
<comment>The maximum amount of tags that are fetched in 1 purge request. This can be
24+
set to a fairly high number (1 million by default), unless you run into resource
25+
limits/timeouts.</comment>
26+
<depends>
27+
<field id="caching_application">1</field>
28+
</depends>
29+
</field>
30+
</group>
31+
</group>
32+
</section>
33+
</system>
34+
</config>

src/etc/config.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
3+
<default>
4+
<system>
5+
<full_page_cache>
6+
<async_varnish>
7+
<varnish_max_header_length>8000</varnish_max_header_length>
8+
<varnish_fetch_tag_limit>1000000</varnish_fetch_tag_limit>
9+
</async_varnish>
10+
</full_page_cache>
11+
</system>
12+
</default>
13+
</config>

src/etc/di.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<?xml version="1.0" ?>
22
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
3+
<type name="IntegerNet\AsyncVarnish\Console\Command\PurgeAsyncTagsCommand">
4+
<arguments>
5+
<argument name="state" xsi:type="object">Magento\Framework\App\State\Proxy</argument>
6+
</arguments>
7+
</type>
38
<type name="Magento\Framework\Console\CommandListInterface">
49
<arguments>
510
<argument name="commands" xsi:type="array">

0 commit comments

Comments
 (0)