Skip to content

Commit 65d3aa7

Browse files
committed
FEATURE: prune everything except reserved keys and currently registered release keys
1 parent eb52081 commit 65d3aa7

4 files changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flowpack\DecoupledContentStore\Command;
6+
7+
use Flowpack\DecoupledContentStore\Core\Domain\ValueObject\RedisInstanceIdentifier;
8+
use Flowpack\DecoupledContentStore\Core\RedisPruneService;
9+
use Neos\Flow\Cli\CommandController;
10+
use Neos\Flow\Annotations as Flow;
11+
12+
13+
class ContentStorePruneCommandController extends CommandController
14+
{
15+
/**
16+
* @Flow\Inject
17+
* @var RedisPruneService
18+
*/
19+
protected $redisPruneService;
20+
21+
public function pruneRedisInstanceCommand(string $redisInstanceIdentifier)
22+
{
23+
$redisInstanceIdentifier = RedisInstanceIdentifier::fromString($redisInstanceIdentifier);
24+
25+
$this->redisPruneService->pruneRedisInstance($redisInstanceIdentifier);
26+
}
27+
28+
}

Classes/Controller/BackendController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Flowpack\DecoupledContentStore\Core\Infrastructure\ContentReleaseLogger;
1010
use Flowpack\DecoupledContentStore\Core\Infrastructure\RedisClientManager;
1111
use Flowpack\DecoupledContentStore\Core\RedisKeyService;
12+
use Flowpack\DecoupledContentStore\Core\RedisPruneService;
1213
use Flowpack\DecoupledContentStore\PrepareContentRelease\Infrastructure\RedisContentReleaseService;
1314
use Flowpack\DecoupledContentStore\ReleaseSwitch\Infrastructure\RedisReleaseSwitchService;
1415
use Flowpack\DecoupledContentStore\Transfer\ContentReleaseCleaner;
@@ -69,6 +70,12 @@ class BackendController extends \Neos\Flow\Mvc\Controller\ActionController
6970
*/
7071
protected $contentReleaseCleaner;
7172

73+
/**
74+
* @Flow\Inject
75+
* @var RedisPruneService
76+
*/
77+
protected $redisPruneService;
78+
7279
/**
7380
* @Flow\InjectConfiguration("redisContentStores")
7481
* @var array
@@ -155,4 +162,12 @@ public function switchContentReleaseOnOtherInstanceAction(string $targetRedisIns
155162

156163
$this->redirect('index', null, null, ['contentStore' => $targetRedisInstanceIdentifier]);
157164
}
165+
166+
public function pruneContentStoreAction(string $redisInstanceIdentifier)
167+
{
168+
$redisInstanceIdentifier = RedisInstanceIdentifier::fromString($redisInstanceIdentifier);
169+
$this->redisPruneService->pruneRedisInstance($redisInstanceIdentifier);
170+
171+
$this->redirect('index', null, null, ['contentStore' => $redisInstanceIdentifier->getIdentifier()]);
172+
}
158173
}

Classes/Core/RedisPruneService.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Flowpack\DecoupledContentStore\Core;
4+
5+
use Flowpack\DecoupledContentStore\Core\Domain\ValueObject\RedisInstanceIdentifier;
6+
use Flowpack\DecoupledContentStore\Core\Infrastructure\RedisClientManager;
7+
use Neos\Flow\Annotations as Flow;
8+
9+
/**
10+
* @Flow\Scope("singleton")
11+
*/
12+
class RedisPruneService
13+
{
14+
// go through all keys in the selected content store
15+
// check wether they are reserved keys or currently active or contain one of the currently registered releases ids
16+
// if not: delete
17+
const PRUNE_LUA_SCRIPT = '
18+
local contentStoreCurrent = redis.call("GET", "contentStore:current")
19+
local contentStoreAllKeys = redis.call("KEYS", "*")
20+
local contentStoreRegisteredReleases = redis.call("ZRANGE", "contentStore:registeredReleases", 0, -1)
21+
local currentContentStoreStart = "contentStore:" .. contentStoreCurrent
22+
23+
local function table_contains_value(tab, val)
24+
for index,value in ipairs(tab) do
25+
if string.find(val, value) then
26+
return true
27+
end
28+
end
29+
return false
30+
end
31+
32+
for index,contentStoreKey in ipairs(contentStoreAllKeys) do
33+
if contentStoreKey ~= "contentStore:current"
34+
and contentStoreKey ~= "contentStore:registeredReleases"
35+
and string.sub(contentStoreKey, 1, string.len(currentContentStoreStart)) ~= currentContentStoreStart
36+
and not table_contains_value(contentStoreRegisteredReleases, contentStoreKey) then
37+
redis.call("DEL", contentStoreKey)
38+
end
39+
end
40+
';
41+
42+
/**
43+
* @Flow\Inject
44+
* @var RedisClientManager
45+
*/
46+
protected $redisClientManager;
47+
48+
49+
public function pruneRedisInstance(RedisInstanceIdentifier $redisInstanceIdentifier)
50+
{
51+
$this->redisClientManager->getRedis($redisInstanceIdentifier)->eval(self::PRUNE_LUA_SCRIPT, []);
52+
}
53+
54+
}

Resources/Private/BackendFusion/Integration/Backend.Index.fusion

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ Flowpack.DecoupledContentStore.BackendController.index = Neos.Fusion:Component {
66
// - redisContentStores: array of all configured content store identifiers
77

88
renderer = Neos.Fusion:Component {
9+
_pruneContentStoreUri = Neos.Fusion:UriBuilder {
10+
action = 'pruneContentStore'
11+
arguments = Neos.Fusion:DataStructure {
12+
redisInstanceIdentifier = ${contentStore}
13+
}
14+
}
915

1016
_renderedTableBody = Neos.Fusion:Loop {
1117
items = ${overviewData}
@@ -78,6 +84,10 @@ Flowpack.DecoupledContentStore.BackendController.index = Neos.Fusion:Component {
7884
</tbody>
7985
</table>
8086

87+
<button form="postHelper" formaction={props._pruneContentStoreUri} type="submit" class="neos-button neos-button-danger" style="margin-top: 300px;">
88+
Prune content store
89+
</button>
90+
8191
<Flowpack.DecoupledContentStore:ListFooter />
8292
</div>
8393
</div>

0 commit comments

Comments
 (0)