Skip to content

Commit

Permalink
Added MemoryCacheStorage and use it in ChangedFilesDetectorTest (#525)
Browse files Browse the repository at this point in the history
Co-authored-by: Markus Staab <markus.staab@redaxo.de>
  • Loading branch information
clxmstaab and staabm committed Jul 28, 2021
1 parent a7f111e commit 687a777
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 20 deletions.
8 changes: 8 additions & 0 deletions config/parameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

declare(strict_types=1);

use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

Expand Down Expand Up @@ -29,4 +30,11 @@

// cache
$parameters->set(Option::CACHE_DIR, sys_get_temp_dir() . '/rector_cached_files');

// use faster in-memory cache in CI.
// CI always starts from scratch, therefore IO intensive caching is not worth it
$runsInGithubAction = getenv('GITHUB_ACTION');
if (false !== $runsInGithubAction) {
$parameters->set(Option::CACHE_CLASS, MemoryCacheStorage::class);
}
};
2 changes: 2 additions & 0 deletions packages-tests/Caching/Detector/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

declare(strict_types=1);

use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::CACHE_DIR, sys_get_temp_dir() . '/_rector_cached_files_test');
$parameters->set(Option::CACHE_CLASS, MemoryCacheStorage::class);
};
12 changes: 6 additions & 6 deletions packages/Caching/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

namespace Rector\Caching;

use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\Caching\ValueObject\Storage\CacheStorageInterface;

final class Cache
{
public function __construct(
private FileCacheStorage $fileCacheStorage
private CacheStorageInterface $cacheStorage
) {
}

Expand All @@ -18,24 +18,24 @@ public function __construct(
*/
public function load(string $key, string $variableKey)
{
return $this->fileCacheStorage->load($key, $variableKey);
return $this->cacheStorage->load($key, $variableKey);
}

/**
* @param mixed $data
*/
public function save(string $key, string $variableKey, $data): void
{
$this->fileCacheStorage->save($key, $variableKey, $data);
$this->cacheStorage->save($key, $variableKey, $data);
}

public function clear(): void
{
$this->fileCacheStorage->clear();
$this->cacheStorage->clear();
}

public function clean(string $cacheKey): void
{
$this->fileCacheStorage->clean($cacheKey);
$this->cacheStorage->clean($cacheKey);
}
}
21 changes: 16 additions & 5 deletions packages/Caching/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Rector\Caching;

use Rector\Caching\ValueObject\Storage\CacheStorageInterface;
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Core\Configuration\Option;
use Symplify\PackageBuilder\Parameter\ParameterProvider;
use Symplify\SmartFileSystem\SmartFileSystem;
Expand All @@ -21,12 +23,21 @@ public function create(): Cache
{
$cacheDirectory = $this->parameterProvider->provideStringParameter(Option::CACHE_DIR);

// ensure cache directory exists
if (! $this->smartFileSystem->exists($cacheDirectory)) {
$this->smartFileSystem->mkdir($cacheDirectory);
$cacheClass = FileCacheStorage::class;
if ($this->parameterProvider->hasParameter(Option::CACHE_CLASS)) {
$cacheClass = $this->parameterProvider->provideStringParameter(Option::CACHE_CLASS);
}

$fileCacheStorage = new FileCacheStorage($cacheDirectory, $this->smartFileSystem);
return new Cache($fileCacheStorage);
if ($cacheClass === FileCacheStorage::class) {
// ensure cache directory exists
if (! $this->smartFileSystem->exists($cacheDirectory)) {
$this->smartFileSystem->mkdir($cacheDirectory);
}

$fileCacheStorage = new FileCacheStorage($cacheDirectory, $this->smartFileSystem);
return new Cache($fileCacheStorage);
}

return new Cache(new MemoryCacheStorage());
}
}
25 changes: 25 additions & 0 deletions packages/Caching/ValueObject/Storage/CacheStorageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Rector\Caching\ValueObject\Storage;

/**
* inspired by https://github.com/phpstan/phpstan-src/blob/560652088406d7461c2c4ad4897784e33f8ab312/src/Cache/CacheStorage.php
*/
interface CacheStorageInterface
{
/**
* @return mixed|null
*/
public function load(string $key, string $variableKey);

/**
* @param mixed $data
*/
public function save(string $key, string $variableKey, $data): void;

public function clean(string $key): void;

public function clear(): void;
}
12 changes: 3 additions & 9 deletions packages/Caching/ValueObject/Storage/FileCacheStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@
/**
* Inspired by https://github.com/phpstan/phpstan-src/blob/1e7ceae933f07e5a250b61ed94799e6c2ea8daa2/src/Cache/FileCacheStorage.php
*/
final class FileCacheStorage
final class FileCacheStorage implements CacheStorageInterface
{
public function __construct(
private string $directory,
private SmartFileSystem $smartFileSystem
) {
}

/**
* @return mixed|null
*/
public function load(string $key, string $variableKey)
{
return (function (string $key, string $variableKey) {
Expand All @@ -45,9 +42,6 @@ public function load(string $key, string $variableKey)
})($key, $variableKey);
}

/**
* @param mixed $data
*/
public function save(string $key, string $variableKey, $data): void
{
$cacheFilePaths = $this->getCacheFilePaths($key);
Expand Down Expand Up @@ -79,9 +73,9 @@ public function save(string $key, string $variableKey, $data): void
}
}

public function clean(string $cacheKey): void
public function clean(string $key): void
{
$cacheFilePaths = $this->getCacheFilePaths($cacheKey);
$cacheFilePaths = $this->getCacheFilePaths($key);

$this->smartFileSystem->remove([
$cacheFilePaths->getFirstDirectory(),
Expand Down
47 changes: 47 additions & 0 deletions packages/Caching/ValueObject/Storage/MemoryCacheStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace Rector\Caching\ValueObject\Storage;

use Rector\Caching\ValueObject\CacheItem;

/**
* inspired by https://github.com/phpstan/phpstan-src/blob/560652088406d7461c2c4ad4897784e33f8ab312/src/Cache/MemoryCacheStorage.php
*/
class MemoryCacheStorage implements CacheStorageInterface
{
/** @var array<string, CacheItem> */
private array $storage = [];

public function load(string $key, string $variableKey)
{
if (!isset($this->storage[$key])) {
return null;
}

$item = $this->storage[$key];
if (!$item->isVariableKeyValid($variableKey)) {
return null;
}

return $item->getData();
}

public function save(string $key, string $variableKey, $data): void
{
$this->storage[$key] = new CacheItem($variableKey, $data);
}

public function clean(string $key): void
{
if (!isset($this->storage[$key])) {
return;
}

unset($this->storage[$key]);
}

public function clear(): void
{
$this->storage = [];
}
}
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ parameters:
- '#Method "decorateReturnWithSpecificType\(\)" returns bool type, so the name should start with is/has/was#'
- '#Method "resolveObjectType\(\)" returns bool type, so the name should start with is/has/was#'

# internal contract, not meant for re-use at rector consumer level
-
message: '#Interface must be located in "Contract" namespace#'
paths:
- packages/Caching/ValueObject/Storage/CacheStorageInterface.php

# resolve later
-
message: '#Use explicit names over dynamic ones#'
Expand Down
10 changes: 10 additions & 0 deletions src/Configuration/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Rector\Core\Configuration;

use JetBrains\PhpStorm\Immutable;
use Rector\Caching\ValueObject\Storage\CacheStorageInterface;
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Symplify\Skipper\ValueObject\Option as SkipperOption;

#[Immutable]
Expand Down Expand Up @@ -111,6 +113,14 @@ final class Option
*/
public const CACHE_DIR = 'cache_dir';

/**
* Cache backend. Most of the time we cache in files, but in ephemeral environment (e.g. CI), a faster `MemoryCacheStorage` can be usefull.
*
* @var class-string<CacheStorageInterface>
* @internal
*/
public const CACHE_CLASS = FileCacheStorage::class;

/**
* @var string
*/
Expand Down

0 comments on commit 687a777

Please sign in to comment.