Sort hook implementations during discovery, not at runtime

Created on 27 May 2023, over 1 year ago

Problem/Motivation

Currently the hook implementations are sorted by priority at runtime.
This can be optimized by doing the sorting at discovery time, so the sorted list can be cached.
The priority is known at that point.

Btw, I am playing around with the code, and might create a PR at some point, but I would like to get some feedback on various issues before I push anything.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

📌 Task
Status

Active

Version

1.2

Component

Code

Created by

🇩🇪Germany donquixote

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @donquixote
  • 🇩🇪Germany donquixote

    Btw, to sort by priority, I generally prefer building nested arrays and using ksort().

    [..]
              $implementations_grouped[$instance->hook][$instance->priority][] = [
                $serviceId,
                $instance->moduleName ?? $moduleName,
                $methodName,
              ];
    [..]
        if ($implementations_grouped) {
          $result[Hook::class] = array_map(
            static function (array $implementations_by_priority): array {
              ksort($implementations_by_priority);
              return array_merge(...$implementations_by_priority);
            },
            $implementations_grouped,
          );
        }
    

    (This will be part of my PR once I get there)

  • 🇩🇪Germany donquixote

    This also makes me wonder if we should have a priority for alter.
    I don't think we need it for replace.

  • 🇦🇺Australia dpi Perth, Australia

    Makes sense to order during discovery.

    I'd rather not have anything meaningful in the keys, so we aren't introducing some kind of unintended API. You can currently everything is in the array value itself.

    Since it will be as discovery process it doesnt need to be ultra-optimised. Im happy with usort, and with the natural PHP array order that gets serialised.

    A general note for future: If this is going to core, I think it would be ideal to introduce a Before/After attribute if the hook in question knows it depends on another. Hux could work out a dependency graph, which would effectively nullify priorities.

    Alter could use a new issue for priorities, but it can be deferred (even as a post-core-merge feature).

  • 🇦🇺Australia dpi Perth, Australia

    Pre-review note: the getters on discovery should be documented to mention they are baked with order already.

  • 🇩🇪Germany donquixote

    I'd rather not have anything meaningful in the keys, so we aren't introducing some kind of unintended API. You can currently everything is in the array value itself.

    The array key is never exposed outside of the class, thanks to the array_merge(..).

    And another benefit is that this sort is stable.
    Last time I checked, php sort functions were not stable. But I could be wrong.
    In my little experiment it looks stable, so maybe they changed it:
    https://3v4l.org/oDK6H

Production build 0.71.5 2024