Skip to content

Commit

Permalink
added instance cache for wildcard listeners in order to save on expen…
Browse files Browse the repository at this point in the history
…sive Str::is calls, which usually goes in dozens of thousands
  • Loading branch information
jarektkaczyk committed Feb 26, 2018
1 parent 2d1364d commit c86efa6
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/Illuminate/Events/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class Dispatcher implements DispatcherContract
*/
protected $wildcards = [];

/**
* Wildcard listeners cache which saves expensive string operations.
*
* @var array
*/
protected $wildcardsCache = [];

/**
* The queue resolver instance.
*
Expand Down Expand Up @@ -82,6 +89,8 @@ public function listen($events, $listener)
protected function setupWildcardListen($event, $listener)
{
$this->wildcards[$event][] = $this->makeListener($listener, true);

$this->wildcardsCache = [];
}

/**
Expand Down Expand Up @@ -281,9 +290,9 @@ public function getListeners($eventName)
{
$listeners = $this->listeners[$eventName] ?? [];

$listeners = array_merge(
$listeners, $this->getWildcardListeners($eventName)
);
$wildcardListeners = $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName);

$listeners = array_merge($listeners, $wildcardListeners);

return class_exists($eventName, false)
? $this->addInterfaceListeners($eventName, $listeners)
Expand All @@ -306,7 +315,7 @@ protected function getWildcardListeners($eventName)
}
}

return $wildcards;
return $this->wildcardsCache[$eventName] = $wildcards;
}

/**
Expand Down
17 changes: 17 additions & 0 deletions tests/Events/EventsDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,23 @@ public function testWildcardListeners()
$this->assertEquals('wildcard', $_SERVER['__event.test']);
}

public function testWildcardListenersCacheFlushing()
{
unset($_SERVER['__event.test']);
$d = new Dispatcher;
$d->listen('foo.*', function () {
$_SERVER['__event.test'] = 'cached_wildcard';
});
$d->fire('foo.bar');
$this->assertEquals('cached_wildcard', $_SERVER['__event.test']);

$d->listen('foo.*', function () {
$_SERVER['__event.test'] = 'new_wildcard';
});
$d->fire('foo.bar');
$this->assertEquals('new_wildcard', $_SERVER['__event.test']);
}

public function testListenersCanBeRemoved()
{
unset($_SERVER['__event.test']);
Expand Down

0 comments on commit c86efa6

Please sign in to comment.