Skip to content

Commit 18b98f5

Browse files
committed
Added scoped event manager support
1 parent 32130cf commit 18b98f5

36 files changed

+445
-380
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
##### xx january 2024
33
- __API__
44
- Upgraded Phpfastcache API to `4.3.0` ([see changes](CHANGELOG_API.md))
5+
- __Events__
6+
- 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).
57
- __Drivers__
68
- Implemented #906 // **Added `RedisCluster` driver support**
79
- __Pool__

docs/EVENTS.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ This is an exhaustive list, and it will be updated as soon as new events will be
6060
- Event callbacks will now receive the `eventName` as an extra _last_ callback parameter (except for `onEveryEvents` callbacks)
6161
- Added `EventManagerInterface::on(array $eventNames, $callback)` method, to subscribe to multiple events in once with the same callback
6262

63+
:warning: Changed in V9.2
64+
65+
As of the V9.2 there is a slight change with the EventManager:
66+
EventManager is now scoped to its own poll if retrieved through `ExtendedCacheItemPoolTrait::->getEventManager()`.
67+
This means, that the behavior is not more consistent:\
68+
An EventManager retrieved through `ExtendedCacheItemPoolTrait::->getEventManager()` will now **ONLY** fire events related to this pool instance.\
69+
However, the global EventManager `EventManager::getInstance()` remains unchanged and will fire any events no matter what pool emitted it.
70+
The order of execution of the events is always the following:
71+
72+
1. Scoped named Event through `ExtendedCacheItemPoolTrait::->getEventManager()->onXxxxxXxxxx(...)`
73+
2. Scoped `onEveryEvent` Event through `ExtendedCacheItemPoolTrait::->getEventManager()->onEveryEvent(...)`
74+
3. Unscoped named event through `EventManager::getInstance()->onXxxxxXxxxx(...)`
75+
4. Unscoped `onEveryEvent` event through `EventManager::getInstance()->onEveryEvent(...)`
76+
6377
## List of active events:
6478
### ItemPool Events
6579
- onCacheGetItem(*Callable* **$callback**)
@@ -189,6 +203,25 @@ This is an exhaustive list, and it will be updated as soon as new events will be
189203
- *ExtendedCacheItemPoolInterface::getItems()*
190204
- *ExtendedCacheItemPoolInterface::getItemsByTag()*
191205
- *ExtendedCacheItemPoolInterface::getItemsAsJsonString()*
206+
- onCacheDriverChecked(*Callable* **$callback**)
207+
- **Callback arguments**
208+
- *ExtendedCacheItemPoolInterface* **$itemPool**
209+
- **Scope**
210+
- ItemPool
211+
- **Description**
212+
- Allow you to bind an event when the driver prerequisites has passed but before it the `driverConnect()` is called.
213+
- **Risky Circular Methods**
214+
- *(none)*
215+
- onCacheDriverConnected(*Callable* **$callback**)
216+
- **Callback arguments**
217+
- *ExtendedCacheItemPoolInterface* **$itemPool**
218+
- *object* **$instance** Internal instance of the backend connect
219+
- **Scope**
220+
- ItemPool
221+
- **Description**
222+
- Allow you to bind an event when the driver backend has been successfully instantiated and connected/authenticated (where applicable).
223+
- **Risky Circular Methods**
224+
- *(none)*
192225
### ItemPool Events (Cluster)
193226
- onCacheReplicationSlaveFallback(*Callable* **$callback**)
194227
- **Callback arguments**

lib/Phpfastcache/Config/AbstractConfigurationOption.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@
1717
namespace Phpfastcache\Config;
1818

1919
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
20+
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
2021
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
2122

2223
abstract class AbstractConfigurationOption implements LockableConfigurationInterface
2324
{
2425
private bool $lockedObject = false;
2526
private ExtendedCacheItemPoolInterface $locker;
27+
28+
protected function getClassName(): string
29+
{
30+
return $this::class;
31+
}
32+
2633
public function lock(ExtendedCacheItemPoolInterface $poolInstance): static
2734
{
2835
$this->lockedObject = true;
@@ -40,21 +47,35 @@ public function isLocked(): bool
4047
return $this->lockedObject;
4148
}
4249

50+
/**
51+
* @throws PhpfastcacheLogicException
52+
* @throws PhpfastcacheInvalidArgumentException
53+
*/
54+
protected function setProperty(string $propertyName, mixed $propertyValue): static
55+
{
56+
$this->enforceLockedProperty($propertyName);
57+
if (property_exists($this, $propertyName)) {
58+
$this->$propertyName = $propertyValue;
59+
return $this;
60+
}
61+
throw new PhpfastcacheInvalidArgumentException("Unknown property $propertyName in {$this->getClassName()} context.");
62+
}
63+
4364
/**
4465
* @throws PhpfastcacheLogicException
4566
*/
46-
protected function enforceLockedProperty(string $method): void
67+
protected function enforceLockedProperty(string $propertyName): void
4768
{
4869
if ($this->lockedObject === true) {
49-
$dbt = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2);
70+
$dbt = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 3);
5071
$cause = $dbt[\array_key_last($dbt)] ?? null;
5172
if ($cause) {
5273
$moreInfo = \sprintf('Caused line %d in %s', $cause['line'], $cause['file']);
5374
}
5475

5576
throw new PhpfastcacheLogicException(\sprintf(
5677
'You can no longer change the configuration "%s" as the cache pool instance is now running. %s',
57-
\lcfirst(\substr($method, 3)),
78+
$propertyName,
5879
$moreInfo ?? ''
5980
));
6081
}

lib/Phpfastcache/Config/IOConfigurationOption.php

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ public function getSecurityKey(): string
4747
*/
4848
public function setSecurityKey(string $securityKey): static
4949
{
50-
$this->enforceLockedProperty(__FUNCTION__);
51-
$this->securityKey = $securityKey;
52-
53-
return $this;
50+
return $this->setProperty('securityKey', $securityKey);
5451
}
5552

5653
/**
@@ -68,9 +65,7 @@ public function isSecureFileManipulation(): bool
6865
*/
6966
public function setSecureFileManipulation(bool $secureFileManipulation): static
7067
{
71-
$this->enforceLockedProperty(__FUNCTION__);
72-
$this->secureFileManipulation = $secureFileManipulation;
73-
return $this;
68+
return $this->setProperty('secureFileManipulation', $secureFileManipulation);
7469
}
7570

7671

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

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

105-
$this->cacheFileExtension = $cacheFileExtension;
106-
return $this;
99+
return $this->setProperty('cacheFileExtension', $cacheFileExtension);
107100
}
108101

109102
/**
@@ -121,9 +114,7 @@ public function getDefaultChmod(): int
121114
*/
122115
public function setDefaultChmod(int $defaultChmod): static
123116
{
124-
$this->enforceLockedProperty(__FUNCTION__);
125-
$this->defaultChmod = $defaultChmod;
126-
return $this;
117+
return $this->setProperty('defaultChmod', $defaultChmod);
127118
}
128119

129120

@@ -142,9 +133,7 @@ public function isPreventCacheSlams(): bool
142133
*/
143134
public function setPreventCacheSlams(bool $preventCacheSlams): static
144135
{
145-
$this->enforceLockedProperty(__FUNCTION__);
146-
$this->preventCacheSlams = $preventCacheSlams;
147-
return $this;
136+
return $this->setProperty('preventCacheSlams', $preventCacheSlams);
148137
}
149138

150139
/**
@@ -162,8 +151,6 @@ public function getCacheSlamsTimeout(): int
162151
*/
163152
public function setCacheSlamsTimeout(int $cacheSlamsTimeout): static
164153
{
165-
$this->enforceLockedProperty(__FUNCTION__);
166-
$this->cacheSlamsTimeout = $cacheSlamsTimeout;
167-
return $this;
154+
return $this->setProperty('cacheSlamsTimeout', $cacheSlamsTimeout);
168155
}
169156
}

lib/Phpfastcache/Core/Pool/CacheItemPoolTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public function getItem(string $key): ExtendedCacheItemInterface
218218
if ($driverArray) {
219219
$driverData = $this->driverUnwrapData($driverArray);
220220

221-
if ($config instanceof IOConfigurationOptionInterface && $this->getConfig()->isPreventCacheSlams()) {
221+
if ($config instanceof IOConfigurationOptionInterface && $config->isPreventCacheSlams()) {
222222
while ($driverData instanceof ItemBatch) {
223223
if ($driverData->getItemDate()->getTimestamp() + $config->getCacheSlamsTimeout() < \time()) {
224224
/**

lib/Phpfastcache/Core/Pool/DriverBaseTrait.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use DateTime;
2020
use DateTimeInterface;
2121
use Phpfastcache\Config\ConfigurationOptionInterface;
22+
use Phpfastcache\Event\Event;
2223
use Phpfastcache\Event\EventManagerDispatcherTrait;
2324
use Phpfastcache\Event\EventManagerInterface;
2425
use Phpfastcache\Exceptions\PhpfastcacheCorruptedDataException;
@@ -50,9 +51,9 @@ trait DriverBaseTrait
5051
protected ConfigurationOptionInterface $config;
5152

5253
/**
53-
* @var object|array<mixed>|null
54+
* @var object|null
5455
*/
55-
protected object|array|null $instance;
56+
protected ?object $instance;
5657

5758
protected string $driverName;
5859

@@ -71,16 +72,19 @@ trait DriverBaseTrait
7172
*/
7273
public function __construct(#[\SensitiveParameter] ConfigurationOptionInterface $config, string $instanceId, EventManagerInterface $em)
7374
{
74-
$this->setEventManager($em);
75+
$this->setEventManager($em->getScopedEventManager($this));
7576
$this->setConfig($config);
7677
$this->instanceId = $instanceId;
7778

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

8284
try {
8385
$this->driverConnect();
86+
$config->lock($this); // Lock the config only after a successful driver connection.
87+
$this->eventManager->dispatch(Event::CACHE_DRIVER_CONNECTED, $this, $this->instance ?? null);
8488
} catch (Throwable $e) {
8589
throw new PhpfastcacheDriverConnectException(
8690
sprintf(
@@ -94,8 +98,6 @@ public function __construct(#[\SensitiveParameter] ConfigurationOptionInterface
9498
0,
9599
$e
96100
);
97-
} finally {
98-
$config->lock($this);
99101
}
100102
}
101103

0 commit comments

Comments
 (0)