Skip to content

Commit

Permalink
Improved extension mechanism performances
Browse files Browse the repository at this point in the history
  • Loading branch information
Geolim4 committed Jan 9, 2024
1 parent 58f77cf commit e96391e
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 42 deletions.
26 changes: 16 additions & 10 deletions lib/Phpfastcache/CacheManager.php
Expand Up @@ -23,6 +23,7 @@
use Phpfastcache\Exceptions\PhpfastcacheDriverException;
use Phpfastcache\Exceptions\PhpfastcacheDriverNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheExtensionNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheExtensionNotInstalledException;
use Phpfastcache\Exceptions\PhpfastcacheInstanceNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
Expand Down Expand Up @@ -59,6 +60,11 @@ class CacheManager
*/
protected static array $driverCustoms = [];

/**
* @var string[]
*/
protected static array $driverExtensions = [];

/**
* @param string $instanceId
* @return ExtendedCacheItemPoolInterface
Expand Down Expand Up @@ -91,6 +97,7 @@ public static function getInstances(): array
* @throws PhpfastcacheDriverCheckException
* @throws PhpfastcacheDriverException
* @throws PhpfastcacheDriverNotFoundException
* @throws PhpfastcacheExtensionNotInstalledException
* @throws PhpfastcacheLogicException
*/
public static function getInstance(string $driver, ?ConfigurationOptionInterface $config = null, ?string $instanceId = null): ExtendedCacheItemPoolInterface
Expand All @@ -116,22 +123,19 @@ public static function getInstance(string $driver, ?ConfigurationOptionInterface
);
} else {
try {
ExtensionManager::loadExtension($driver);
self::$driverExtensions[$driver] = ExtensionManager::getExtension($driver);
return CacheManager::getInstance($driver, $config, $instanceId);
} catch (PhpfastcacheExtensionNotFoundException) {
// Temporary check until v10
$extensionWarning = '';
if (in_array($driver, ['Arangodb', 'Couchdb', 'Dynamodb', 'Firestore', 'Mongodb', 'Solr'], true)) {
$extensionWarning .= sprintf(
'However, it seems that you are using a driver which is now an extension. Run the following command to solve this issue: %s',
if (in_array($driver, ExtensionManager::KNOWN_EXTENSION_NAMES, true)) {
throw new PhpfastcacheExtensionNotInstalledException(sprintf(
'You requested a driver which is now an extension. Run the following command to solve this issue: %s',
sprintf('composer install phpfastcache/%s-extension', strtolower($driver))
);
));
}
throw new PhpfastcacheDriverNotFoundException(sprintf(
'The driver "%s" does not exist or does not implement %s. %s',
'The driver "%s" does not exist or does not implement %s.',
$driver,
ExtendedCacheItemPoolInterface::class,
$extensionWarning,
));
}
}
Expand Down Expand Up @@ -191,7 +195,9 @@ public static function normalizeDriverName(string $driverName): string
*/
public static function getDriverClass(string $driverName): string
{
if (!empty(self::$driverCustoms[$driverName])) {
if (!empty(self::$driverExtensions[$driverName])) {
$driverClass = self::$driverExtensions[$driverName];
} elseif (!empty(self::$driverCustoms[$driverName])) {
$driverClass = self::$driverCustoms[$driverName];
} elseif (!empty(self::$driverOverrides[$driverName])) {
$driverClass = self::$driverOverrides[$driverName];
Expand Down
Expand Up @@ -16,6 +16,6 @@

namespace Phpfastcache\Exceptions;

class PhpfastcacheExtensionNotFoundException extends PhpfastcacheDriverException
class PhpfastcacheExtensionNotFoundException extends PhpfastcacheDriverNotFoundException
{
}
@@ -0,0 +1,21 @@
<?php

/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/

declare(strict_types=1);

namespace Phpfastcache\Exceptions;

class PhpfastcacheExtensionNotInstalledException extends PhpfastcacheDriverNotFoundException
{
}
64 changes: 33 additions & 31 deletions lib/Phpfastcache/ExtensionManager.php
Expand Up @@ -16,65 +16,67 @@

namespace Phpfastcache;

use Phpfastcache\Exceptions\PhpfastcacheDriverNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheExtensionNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
use Phpfastcache\Exceptions\PhpfastcacheUnsupportedOperationException;
use Phpfastcache\Helper\UninstanciableObjectTrait;

/**
* @internal This extension manager is meant to manager officials Phpfastcache's extensions.
* @see \Phpfastcache\CacheManager::addCustomDriver() to add you own drivers.
*/
final class ExtensionManager
{
use UninstanciableObjectTrait;

public const KNOWN_EXTENSION_NAMES = [
'Arangodb',
'Couchbasev4',
'Couchdb',
'Dynamodb',
'Firestore',
'Mongodb',
'Solr'
];

/**
* @var array<string, string>
*/
protected static array $registeredExtensions = [];

public static function registerExtension(string $extensionName, string $driverClassName): void
{
if (!str_starts_with($driverClassName, ltrim('Phpfastcache\\Extensions\\', '\\'))) {
throw new PhpfastcacheInvalidArgumentException(
'Only extensions from "\\Phpfastcache\\Extensions\\" namespace are allowed. Use CacheManager::addCustomDriver() to create your own extensions.'
);
}
self::$registeredExtensions[$extensionName] = $driverClassName;
}

/**
* Autoload all the discoverable extensions.
*
* @return void
* @throws PhpfastcacheExtensionNotFoundException
* @throws PhpfastcacheInvalidArgumentException
* @throws PhpfastcacheLogicException
* @throws PhpfastcacheUnsupportedOperationException
*/
public static function autoloadExtensions(): void
public static function extensionExists(string $extensionName): bool
{
foreach (self::$registeredExtensions as $extension) {
self::loadExtension($extension);
}
return isset(self::$registeredExtensions[$extensionName]);
}

/**
* @param string $name
* @return void
* @return string
* @throws PhpfastcacheExtensionNotFoundException
* @throws PhpfastcacheInvalidArgumentException
* @throws PhpfastcacheLogicException
* @throws PhpfastcacheUnsupportedOperationException
*/
public static function loadExtension(string $name): void
public static function getExtension(string $name): string
{
if (!CacheManager::customDriverExists($name)) {
if (isset(self::$registeredExtensions[$name])) {
CacheManager::addCustomDriver($name, self::$registeredExtensions[$name]);
} else {
throw new PhpfastcacheExtensionNotFoundException(
sprintf(
'Unable too find the %s extension. Make sure that you you added through composer: `composer require phpfastcache/%s-extension`',
$name,
strtolower($name)
)
);
}
if (isset(self::$registeredExtensions[$name])) {
return self::$registeredExtensions[$name];
} else {
throw new PhpfastcacheExtensionNotFoundException(
sprintf(
'Unable too find the %s extension. Make sure that you you added through composer: `composer require phpfastcache/%s-extension`',
$name,
strtolower($name)
)
);
}
}
}
66 changes: 66 additions & 0 deletions tests/cases/ExtensionManager.test.php
@@ -0,0 +1,66 @@
<?php

/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/

use Phpfastcache\CacheManager;
use Phpfastcache\Exceptions\PhpfastcacheDriverNotFoundException;
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
use Phpfastcache\Exceptions\PhpfastcacheExtensionNotInstalledException;
use Phpfastcache\Tests\Helper\TestHelper;

chdir(__DIR__);
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../mock/Autoload.php';
$testHelper = new TestHelper('Apcu test (CRUD)');

try {
$pool = CacheManager::getInstance('Arangodb');
$testHelper->assertFail('CacheManager didnt thrown an Exception');
} catch (PhpfastcacheExtensionNotInstalledException) {
$testHelper->assertPass('CacheManager thrown a PhpfastcacheExtensionNotInstalledException.');
} catch (\Throwable $e) {
$testHelper->assertFail('CacheManager thrown a ' . $e::class);
}

try {
$pool = CacheManager::getInstance(bin2hex(random_bytes(8)));
$testHelper->assertFail('CacheManager didnt thrown an Exception');
} catch (PhpfastcacheDriverNotFoundException $e) {
if ($e::class === PhpfastcacheDriverNotFoundException::class) {
$testHelper->assertPass('CacheManager thrown a PhpfastcacheDriverNotFoundException.');
} else {
$testHelper->assertFail('CacheManager thrown a ' . $e::class);
}
} catch (\Throwable $e) {
$testHelper->assertFail('CacheManager thrown a ' . $e::class);
}

try {
\Phpfastcache\ExtensionManager::registerExtension(
'Extensiontest',
\Phpfastcache\Extensions\Drivers\Extensiontest\Driver::class
);
$testHelper->assertPass('Registered a test extension.');
} catch (PhpfastcacheInvalidArgumentException) {
$testHelper->assertFail('Failed to register a test extension.');
}

try {
CacheManager::getInstance('Extensiontest');
$testHelper->assertPass('Retrieved a test extension cache pool.');
} catch (PhpfastcacheDriverNotFoundException) {
$testHelper->assertFail('Failed to retrieve a test extension cache pool.');
}


$testHelper->terminateTest();
@@ -0,0 +1,42 @@
<?php
/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/

namespace Phpfastcache\Extensions\Drivers\Extensiontest;

use Phpfastcache\Drivers\Files\Config as FilesConfig;

class Config extends FilesConfig
{
/**
* @var bool
*/
protected bool $customOption = true;

/**
* @return bool
*/
public function isCustomOption(): bool
{
return $this->customOption;
}

/**
* @param bool $customOption
* @return Config
*/
public function setCustomOption(bool $customOption): Config
{
$this->customOption = $customOption;
return $this;
}
}
@@ -0,0 +1,21 @@
<?php
/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/

namespace Phpfastcache\Extensions\Drivers\Extensiontest;

use Phpfastcache\Drivers\Files\Driver as FilesDriver;

class Driver extends FilesDriver
{

}
22 changes: 22 additions & 0 deletions tests/mock/Phpfastcache/Extensions/Drivers/Extensiontest/Item.php
@@ -0,0 +1,22 @@
<?php
/**
*
* This file is part of Phpfastcache.
*
* @license MIT License (MIT)
*
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
*
* @author Georges.L (Geolim4) <contact@geolim4.com>
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
*/

namespace Phpfastcache\Extensions\Drivers\Extensiontest;

use Phpfastcache\Drivers\Files\Item as FilesItem;


class Item extends FilesItem
{

}

0 comments on commit e96391e

Please sign in to comment.