Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Freescout appears to use
Eventy
to allow modules to customize certain aspects of freescout, for example the usergetFullName
:https://github.com/freescout-helpdesk/freescout/blob/40fc84546168c7fed1eacf55759ff008371815f4/app/User.php#L216
Unfortunately, this eventy library appears to be quite inefficient, especially when you have large amounts of listeners (it does a
O(n)
search through all listeners globally to find matching ones, plus each time does aO(n log n)
sort by priority).For example, on an instance I was profiling, there were ~120 listeners, thus making a single (!)
User::getFullName
take a whopping 3ms (with ~100getFullName
calls for listing assignable users this has a major impact; and that's just for thegetFullName
calls).This PR overrides Eventy, to replace its internal data structure to be more efficient (keyed by the hook).
In total, this reduced mailbox loading times for my organization from ~1.5s to ~0.5s.
Note: I barely know PHP (in fact most of this code was generated by Copilot), so the code probably is very bad ^^ If there's something that can be done better let me know.
Also note that technically I'm changing the (public)
getListeners
function argument types here. This method only appears to be used inside Eventy, but this could still cause problems (it works on my instance though).