update lock clucknut
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 14s
Build, Push and Deploy / build-and-push (push) Successful in 3m14s
Build, Push and Deploy / deploy-staging (push) Successful in 25s
Build, Push and Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-18 20:32:18 +07:00
parent 4554035227
commit dcaf267458
3359 changed files with 153185 additions and 205489 deletions

View File

@@ -36,6 +36,9 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
private ?\SplObjectStorage $callStack = null;
private array $wrappedListeners = [];
private array $orphanedEvents = [];
private array $dispatchDepth = [];
private array $calledListenerInfos = [];
private array $calledOriginalListeners = [];
private string $currentRequestHash = '';
public function __construct(
@@ -142,20 +145,20 @@ public function dispatch(object $event, ?string $eventName = null): object
public function getCalledListeners(?Request $request = null): array
{
if (null === $this->callStack) {
if (!$this->calledListenerInfos) {
return [];
}
$hash = $request ? spl_object_hash($request) : null;
$called = [];
foreach ($this->callStack as $listener) {
[$eventName, $requestHash] = $this->callStack->getInfo();
foreach ($this->calledListenerInfos as $requestHash => $infos) {
if (null === $hash || $hash === $requestHash) {
$called[] = $listener->getInfo($eventName);
$called[] = $infos;
}
}
return $called;
return $called ? array_merge(...$called) : [];
}
public function getNotCalledListeners(?Request $request = null): array
@@ -172,16 +175,14 @@ public function getNotCalledListeners(?Request $request = null): array
$hash = $request ? spl_object_hash($request) : null;
$calledListeners = [];
if (null !== $this->callStack) {
foreach ($this->callStack as $calledListener) {
[, $requestHash] = $this->callStack->getInfo();
if (null === $hash || $hash === $requestHash) {
$calledListeners[] = $calledListener->getWrappedListener();
}
foreach ($this->calledOriginalListeners as $requestHash => $eventListeners) {
if (null === $hash || $hash === $requestHash) {
$calledListeners[] = array_merge(...array_values($eventListeners));
}
}
$calledListeners = $calledListeners ? array_merge(...$calledListeners) : [];
$notCalled = [];
foreach ($allListeners as $eventName => $listeners) {
@@ -218,6 +219,9 @@ public function reset(): void
$this->callStack = null;
$this->orphanedEvents = [];
$this->currentRequestHash = '';
$this->dispatchDepth = [];
$this->calledListenerInfos = [];
$this->calledOriginalListeners = [];
}
/**
@@ -247,6 +251,8 @@ protected function afterDispatch(string $eventName, object $event): void
private function preProcess(string $eventName): void
{
$this->dispatchDepth[$eventName] = ($this->dispatchDepth[$eventName] ?? 0) + 1;
if (!$this->dispatcher->hasListeners($eventName)) {
$this->orphanedEvents[$this->currentRequestHash][] = $eventName;
@@ -265,6 +271,8 @@ private function preProcess(string $eventName): void
private function postProcess(string $eventName): void
{
--$this->dispatchDepth[$eventName];
unset($this->wrappedListeners[$eventName]);
$skipped = false;
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
@@ -282,10 +290,16 @@ private function postProcess(string $eventName): void
if ($listener->wasCalled()) {
$this->logger?->debug('Notified event "{event}" to listener "{listener}".', $context);
} else {
unset($this->callStack[$listener]);
$original = $listener->getWrappedListener();
if (!\in_array($original, $this->calledOriginalListeners[$this->currentRequestHash][$eventName] ?? [], true)) {
$this->calledOriginalListeners[$this->currentRequestHash][$eventName][] = $original;
$this->calledListenerInfos[$this->currentRequestHash][] = $listener->getInfo($eventName);
}
}
unset($this->callStack[$listener]);
if (null !== $this->logger && $skipped) {
$this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context);
}
@@ -296,6 +310,28 @@ private function postProcess(string $eventName): void
$skipped = true;
}
}
if (0 < $this->dispatchDepth[$eventName]) {
return;
}
// Clean up stale callStack entries left by nested same-event dispatches
$stale = [];
foreach ($this->callStack as $listener) {
if ($this->callStack->getInfo()[0] === $eventName) {
$stale[] = $listener;
}
}
foreach ($stale as $listener) {
if ($listener->wasCalled()) {
$original = $listener->getWrappedListener();
if (!\in_array($original, $this->calledOriginalListeners[$this->currentRequestHash][$eventName] ?? [], true)) {
$this->calledOriginalListeners[$this->currentRequestHash][$eventName][] = $original;
$this->calledListenerInfos[$this->currentRequestHash][] = $listener->getInfo($eventName);
}
}
unset($this->callStack[$listener]);
}
}
private function sortNotCalledListeners(array $a, array $b): int