Event priorities #449
mindplay-dk
started this conversation in
Ideas
Replies: 1 comment 2 replies
-
That's a really good point and I also stumbled over it multiple times now, but didn't think about a better solution like you did. Thanks for pointing it out! I see that definiting dependencies makes much more sense, however, I still fail to see how it could look like in practise. Do you have an example? I have two use-cases that could be covered in that example. Both example assume we have a system listener (like core listener that is always running, like http.onRequest.
How would to define that? I assume we need to have some kind of reference to http.onRequest in order to correctly sort it. Would love to see with what API you come up with. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I'm still in the "curious about Deepkit" phase, but haven't gone very deep yet.
But I noticed something in one of your screenshots and thought I would bring this up for discussion.
Looking at the columns, the properties of your event model, this is very similar to something I built a long time ago, and ended up regretting: manually specifying event listener priorities. (by the way, these are event listeners - the title says "events".)
Numeric event priorities are problematic for two main reasons:
They don't explain themselves. As someone trying to read the code, what you get is a number, which may be less/more or equal than some other numbers, but this approach isn't declarative - nothing explains why these numbers are what they are. Yes, they control the event listener priorities - but nothing explains why specifically those numbers were selected. They don't communicate any real intent.
Numeric event priorities are fragile. This ranges from little issues, such as users not understanding how priorities are resolved if they're equal - to bigger issues, such as team settings, where one developer changing their priorities can adversely affect another developer's code and break the system. Or still worse, in an open source setting, you don't have any control of third-party modules changing their priorities - if your event listener is supposed to run between two other event listeners, in some cases, that may not even be possible.
We've all seen lots of systems, even large popular frameworks, adopting this approach, and it's an obvious fix for the immediate problem - I just don't believe it's very practical or viable as a long-term solution.
After lots of thinking and experimentation, I eventually asked: why do we need priorities? what problem are we trying to solve?
The answer I came up with is dependencies.
Usually, when priorities are useful or important, the underlying reason is dependencies - the most common issue is, I need this other listener to run first, or produce some bit of data or content required by my listener; a dependency.
The solution was proprietary, so I can't show you a working solution for this exact problem, but I can show you a very similar problem and solution:
https://github.com/mindplay-dk/implant
This package manages
<script>
and<link>
tags on a page - while the controllers and views are running, they add scripts and other assets that need to be added to<head>
or<body>
(by a layout template that renders those tags) and so on.A previous solution did in fact use numeric priorities, and exhibited the same problems I described above. For example, someone would add jQuery, someone else would add a jQuery plugin, and you would make sure jQuery goes first by assigning it a lower number. Things start to get crazy when you have a jQuery plugin depending on another jQuery plugin, and possible other scripts, and so on.
Long story short, a more reliable solution is topological sorting.
Instead of specifying numbers, you specify dependencies, and a topological sort figures out the priorities. This approach is declarative and generally more robust - for example, if your dependencies can't be sorted (cycles!) you would get an error, rather than some random undefined behavior. Someone else changing their priorities isn't going to quietly break or override something else. It's much more reliable in a team or open-source setting.
The priority model for an event bus is a bit more complex than this simple asset manager. If this topic has caught your interest, I could say more about it, but I'll end it here for now, to see if this is something anyone is interested in addressing. 🙂
Beta Was this translation helpful? Give feedback.
All reactions