Skip to content

Commit

Permalink
Added scoped event manager support
Browse files Browse the repository at this point in the history
  • Loading branch information
Geolim4 committed Dec 16, 2023
1 parent 32130cf commit 18b98f5
Show file tree
Hide file tree
Showing 36 changed files with 445 additions and 380 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
##### xx january 2024
- __API__
- Upgraded Phpfastcache API to `4.3.0` ([see changes](CHANGELOG_API.md))
- __Events__
- EventManager is now scoped to its own poll if retrieved through `ExtendedCacheItemPoolTrait::->getEventManager()`. Global EventManager `EventManager::getInstance()` remains unchanged, see [EVENTS.md](./docs/EVENTS.md).
- __Drivers__
- Implemented #906 // **Added `RedisCluster` driver support**
- __Pool__
Expand Down
33 changes: 33 additions & 0 deletions docs/EVENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ This is an exhaustive list, and it will be updated as soon as new events will be
- Event callbacks will now receive the `eventName` as an extra _last_ callback parameter (except for `onEveryEvents` callbacks)
- Added `EventManagerInterface::on(array $eventNames, $callback)` method, to subscribe to multiple events in once with the same callback

:warning: Changed in V9.2

As of the V9.2 there is a slight change with the EventManager:
EventManager is now scoped to its own poll if retrieved through `ExtendedCacheItemPoolTrait::->getEventManager()`.
This means, that the behavior is not more consistent:\
An EventManager retrieved through `ExtendedCacheItemPoolTrait::->getEventManager()` will now **ONLY** fire events related to this pool instance.\
However, the global EventManager `EventManager::getInstance()` remains unchanged and will fire any events no matter what pool emitted it.
The order of execution of the events is always the following:

1. Scoped named Event through `ExtendedCacheItemPoolTrait::->getEventManager()->onXxxxxXxxxx(...)`
2. Scoped `onEveryEvent` Event through `ExtendedCacheItemPoolTrait::->getEventManager()->onEveryEvent(...)`
3. Unscoped named event through `EventManager::getInstance()->onXxxxxXxxxx(...)`
4. Unscoped `onEveryEvent` event through `EventManager::getInstance()->onEveryEvent(...)`

## List of active events:
### ItemPool Events
- onCacheGetItem(*Callable* **$callback**)
Expand Down Expand Up @@ -189,6 +203,25 @@ This is an exhaustive list, and it will be updated as soon as new events will be
- *ExtendedCacheItemPoolInterface::getItems()*
- *ExtendedCacheItemPoolInterface::getItemsByTag()*
- *ExtendedCacheItemPoolInterface::getItemsAsJsonString()*
- onCacheDriverChecked(*Callable* **$callback**)
- **Callback arguments**
- *ExtendedCacheItemPoolInterface* **$itemPool**
- **Scope**
- ItemPool
- **Description**
- Allow you to bind an event when the driver prerequisites has passed but before it the `driverConnect()` is called.
- **Risky Circular Methods**
- *(none)*
- onCacheDriverConnected(*Callable* **$callback**)
- **Callback arguments**
- *ExtendedCacheItemPoolInterface* **$itemPool**
- *object* **$instance** Internal instance of the backend connect
- **Scope**
- ItemPool
- **Description**
- Allow you to bind an event when the driver backend has been successfully instantiated and connected/authenticated (where applicable).
- **Risky Circular Methods**
- *(none)*
### ItemPool Events (Cluster)
- onCacheReplicationSlaveFallback(*Callable* **$callback**)
- **Callback arguments**
Expand Down
27 changes: 24 additions & 3 deletions lib/Phpfastcache/Config/AbstractConfigurationOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@
namespace Phpfastcache\Config;

use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
use Phpfastcache\Exceptions\PhpfastcacheLogicException;

abstract class AbstractConfigurationOption implements LockableConfigurationInterface
{
private bool $lockedObject = false;
private ExtendedCacheItemPoolInterface $locker;

protected function getClassName(): string
{
return $this::class;
}

public function lock(ExtendedCacheItemPoolInterface $poolInstance): static
{
$this->lockedObject = true;
Expand All @@ -40,21 +47,35 @@ public function isLocked(): bool
return $this->lockedObject;
}

/**
* @throws PhpfastcacheLogicException
* @throws PhpfastcacheInvalidArgumentException
*/
protected function setProperty(string $propertyName, mixed $propertyValue): static
{
$this->enforceLockedProperty($propertyName);
if (property_exists($this, $propertyName)) {
$this->$propertyName = $propertyValue;
return $this;
}
throw new PhpfastcacheInvalidArgumentException("Unknown property $propertyName in {$this->getClassName()} context.");
}

/**
* @throws PhpfastcacheLogicException
*/
protected function enforceLockedProperty(string $method): void
protected function enforceLockedProperty(string $propertyName): void
{
if ($this->lockedObject === true) {
$dbt = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$dbt = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 3);
$cause = $dbt[\array_key_last($dbt)] ?? null;
if ($cause) {
$moreInfo = \sprintf('Caused line %d in %s', $cause['line'], $cause['file']);
}

throw new PhpfastcacheLogicException(\sprintf(
'You can no longer change the configuration "%s" as the cache pool instance is now running. %s',
\lcfirst(\substr($method, 3)),
$propertyName,
$moreInfo ?? ''
));
}
Expand Down
25 changes: 6 additions & 19 deletions lib/Phpfastcache/Config/IOConfigurationOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ public function getSecurityKey(): string
*/
public function setSecurityKey(string $securityKey): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->securityKey = $securityKey;

return $this;
return $this->setProperty('securityKey', $securityKey);
}

/**
Expand All @@ -68,9 +65,7 @@ public function isSecureFileManipulation(): bool
*/
public function setSecureFileManipulation(bool $secureFileManipulation): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->secureFileManipulation = $secureFileManipulation;
return $this;
return $this->setProperty('secureFileManipulation', $secureFileManipulation);
}


Expand All @@ -90,7 +85,6 @@ public function getCacheFileExtension(): string
*/
public function setCacheFileExtension(string $cacheFileExtension): static
{
$this->enforceLockedProperty(__FUNCTION__);
$safeFileExtensions = \explode('|', IOConfigurationOptionInterface::SAFE_FILE_EXTENSIONS);

if (\str_contains($cacheFileExtension, '.')) {
Expand All @@ -102,8 +96,7 @@ public function setCacheFileExtension(string $cacheFileExtension): static
);
}

$this->cacheFileExtension = $cacheFileExtension;
return $this;
return $this->setProperty('cacheFileExtension', $cacheFileExtension);
}

/**
Expand All @@ -121,9 +114,7 @@ public function getDefaultChmod(): int
*/
public function setDefaultChmod(int $defaultChmod): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->defaultChmod = $defaultChmod;
return $this;
return $this->setProperty('defaultChmod', $defaultChmod);
}


Expand All @@ -142,9 +133,7 @@ public function isPreventCacheSlams(): bool
*/
public function setPreventCacheSlams(bool $preventCacheSlams): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->preventCacheSlams = $preventCacheSlams;
return $this;
return $this->setProperty('preventCacheSlams', $preventCacheSlams);
}

/**
Expand All @@ -162,8 +151,6 @@ public function getCacheSlamsTimeout(): int
*/
public function setCacheSlamsTimeout(int $cacheSlamsTimeout): static
{
$this->enforceLockedProperty(__FUNCTION__);
$this->cacheSlamsTimeout = $cacheSlamsTimeout;
return $this;
return $this->setProperty('cacheSlamsTimeout', $cacheSlamsTimeout);
}
}
2 changes: 1 addition & 1 deletion lib/Phpfastcache/Core/Pool/CacheItemPoolTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public function getItem(string $key): ExtendedCacheItemInterface
if ($driverArray) {
$driverData = $this->driverUnwrapData($driverArray);

if ($config instanceof IOConfigurationOptionInterface && $this->getConfig()->isPreventCacheSlams()) {
if ($config instanceof IOConfigurationOptionInterface && $config->isPreventCacheSlams()) {
while ($driverData instanceof ItemBatch) {
if ($driverData->getItemDate()->getTimestamp() + $config->getCacheSlamsTimeout() < \time()) {
/**
Expand Down
12 changes: 7 additions & 5 deletions lib/Phpfastcache/Core/Pool/DriverBaseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use DateTime;
use DateTimeInterface;
use Phpfastcache\Config\ConfigurationOptionInterface;
use Phpfastcache\Event\Event;
use Phpfastcache\Event\EventManagerDispatcherTrait;
use Phpfastcache\Event\EventManagerInterface;
use Phpfastcache\Exceptions\PhpfastcacheCorruptedDataException;
Expand Down Expand Up @@ -50,9 +51,9 @@ trait DriverBaseTrait
protected ConfigurationOptionInterface $config;

/**
* @var object|array<mixed>|null
* @var object|null
*/
protected object|array|null $instance;
protected ?object $instance;

protected string $driverName;

Expand All @@ -71,16 +72,19 @@ trait DriverBaseTrait
*/
public function __construct(#[\SensitiveParameter] ConfigurationOptionInterface $config, string $instanceId, EventManagerInterface $em)
{
$this->setEventManager($em);
$this->setEventManager($em->getScopedEventManager($this));
$this->setConfig($config);
$this->instanceId = $instanceId;

if (!$this->driverCheck()) {
throw new PhpfastcacheDriverCheckException(\sprintf(ExtendedCacheItemPoolInterface::DRIVER_CHECK_FAILURE, $this->getDriverName()));
}
$this->eventManager->dispatch(Event::CACHE_DRIVER_CHECKED, $this);

try {
$this->driverConnect();
$config->lock($this); // Lock the config only after a successful driver connection.
$this->eventManager->dispatch(Event::CACHE_DRIVER_CONNECTED, $this, $this->instance ?? null);
} catch (Throwable $e) {
throw new PhpfastcacheDriverConnectException(
sprintf(
Expand All @@ -94,8 +98,6 @@ public function __construct(#[\SensitiveParameter] ConfigurationOptionInterface
0,
$e
);
} finally {
$config->lock($this);
}
}

Expand Down
Loading

0 comments on commit 18b98f5

Please sign in to comment.