.
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | interdiff.txt | 14.46 KB | neclimdul |
| #23 | plugins-derivatives-23.patch | 21.77 KB | neclimdul |
| #22 | plugins-derivatives-22.patch | 17.57 KB | effulgentsia |
| #19 | plugins-derivatives-19.patch | 20.52 KB | effulgentsia |
| #16 | plugins-derivatives-16.patch | 26.62 KB | effulgentsia |
Comments
Comment #1
effulgentsia commentedThere's probably a bunch needed for this, but here's a tiny start.
Comment #2
neclimdulYeah we need to kill the constructor entirely from feedback from eclipsegc. getting the base discovery class right to cover the right logic is proving hard but I'm close.
Comment #3
effulgentsia commentedneclimdul has a plugins-derivatives branch, and EclipseGc is reviewing it. Leaving this issue open so people can track what's happening, but setting to "needs work" since #1 is obsolete.
Comment #4
effulgentsia commentedAlso upping this to critical since this is the most significant blocker to posting an updated patch to #1497366: Introduce Plugin System to Core.
Comment #5
eclipsegc commentedOK, I don't remember which patch effulgentsia had me apply before I started working, perhaps he can glance at it and make a note to clarify my stupidity for not documenting it myself. That being said, I have a 8 tests for derivatives in this. I _THINK_ this will work, but I'm going to have to actually give blocks a try to see how this pans out, still this is a good first try I think.
Eclipse
Comment #6
effulgentsia commentedThis adjusts for #1529162-36: Decouple plugin type discovery from plugin discovery, resolving the comment in #5. My review to follow.
Comment #7
effulgentsia commentedWhy do we want this static? Derivatives should be per-plugin, shouldn't they? If static, 2 different plugins using the same derivative class will each return all derivatives for both plugins? That seems odd to me.
I don't think we want the abstract class basing anything off this property, which might only be used by some discovery classes.
The abstract class didn't buy us much if we need to do all this.
Is this relevant to this issue?
This seems to be the only change to ConfigDiscovery? If our abstract class is right, we should be able to base ConfigDiscovery on it as well.
Thanks for these. They help me understand our needs more.
I haven't yet looked at how this patch compares with neclimdul's work in the plugins-derivatives branch, but I have a feeling we may all need to sync up again soon if we want to avoid diverging too much.
Comment #8
eclipsegc commentedThis is static because it IS a 1 to 1 relationship between derivative classes and their corresponding plugin definition (which is why I favored consolidating the classes), however, I can't think of a situation where the getDerivatives() method would need anything internal to the class itself, so from a utility standpoint, having the method as a static means we can utilize it in the UI without a full class instance. I'm not sure if that's a good enough reasoning for it to be static, especially since I'm advocating we pick one method or another (either plugins provide their own derivative support, or we have a separate class for that, but both seems to turn the code to spaghetti imo).
In short, no two plugins are likely to ever have the same discovery methodology. The only ones that would come close are field based plugins, but I don't believe I've written two of those with the same getDerivatives() method yet, so I'm pretty sure the logic here is sound.
You're totally right, I dunno why I changed that.
I simplified this further still, but it actually buys us a lot since every discovery method has a different way of getting the plugins, but roughly the same way of getting derivatives, and this helps us there. New code is better, take a look.
Yes, to get tests passing I had to do a little in the factory, so it's definitely relevant.
Quite a few more changes beyond this in the new code base, I still don't have tests for config discovery yet, but I'm pretty confident they could be written at this point easily enough, and the 10 tests I have working against static are a good map of what needs testing.
And, another derivatives patch:
Comment #9
effulgentsia commentedThanks!
This is a reroll (with some very minor tweaks) that rebases to #1540206-14: Allow self inspection on instantiated plugin objects. In other words, to see this in context, apply that patch first, then this one on top. My reasoning is I think that patch is close to being committed, and I think there's things there we want to leverage in this issue. I'll post another patch here soon (as a way to express some ideas I have) with an interdiff relative to this one, so we can pick it apart and cherry pick as needed.
Comment #10
effulgentsia commentedOk, I went further with this than I expected, so these patches are large. Some key things in here:
- I made both getDerivative() and getDerivatives() static, not just the latter.
- Because they're static, I made them take $pluginType and $pluginId as parameters, because even if 99% of implementations won't need them (1 DerivativeInterface class per plugin), I don't think we should require that assumption.
- I removed DiscoveryAbstract and moved that logic to DerivativeDiscovery.
- I removed the test derivative class and moved that logic to TestPlugin, since you said above that that makes more sense, and I agree.
Perhaps we can chat about it tomorrow if that helps. This is all untested and needs polish, but I wanted to get these ideas in front of you to review.
Comment #11
neclimdulI'm still not convinced of the static methods. It seems like we're making them static because ctools did and I can't find a good reason to do it.
I also like the the approach in my branch which seems to leave a much simpler discovery class and which the change I just pushed a simple conversion process of extending DerivativeDiscoveryBase and renaming your getPluginDefinition/getPluginDefinitions functions to loadPluginDefinition/loadPluginDefinitions.
Comment #12
effulgentsia commentedHere's a patch rebased to #1540206-14: Allow self inspection on instantiated plugin objects as in #9, along with an interdiff relative to #9. Tests are passing.
A reason for making them static is to allow the plugin class itself to implement DerivativeInterface for itself, instead of requiring a separate class. This makes sense if you think about blocks for example, where it's logical for the SystemMenuBlock class to implement its functionality and also implement methods that return its derivatives (a block per system menu). But, we shouldn't need to instatiate a SystemMenuBlock instance to ask the class for its derivatives. This patch includes a test for this.
I think the approach in this patch also leaves a pretty simple StaticDiscovery and ConfigDiscovery implementations. The main difference here is that instead of inheriting from DiscoveryAbstract, it composes a DerivateDiscovery object. And I prefer composition here to inheritance, because DerivativeDiscovery (or in your branch, DiscoveryAbstract) contains some arbitrary decisions (e.g., using a colon delimiter) that in my opinion should be possible to swap out without needing to make changes to StaticDiscovery/ConfigDiscovery.
The patch is large, but I think it's mostly just about these 2 design goals.
Comment #13
neclimdulI'm still not convinced. committing to a static method means we can never do anything like pass the global container or a database object to the constructor.
Comment #14
eclipsegc commentedHmmm... can we solve this by just passing an options array to both static methods that we know we won't need 99% of the time? I hear what you're saying here though, but Alex's point about us not being able to use this on the plugin class w/o static methods is really valid, and I'd REALLY like to not lose that now that I've got it :-D
Eclipse
Comment #15
effulgentsia commentedHow about supporting both a non-static interface and a static one? Like in this patch. The full patch is still relative to #1540206-14: Allow self inspection on instantiated plugin objects (I have not rebased to yched's follow-up patches in that issue), and the interdiff is relative to #12.
Comment #16
effulgentsia commentedThis is rerolled to apply directly on plugins-next, so that it can proceed independently of #1540206: Allow self inspection on instantiated plugin objects, which requires more discussion.
Comment #17
neclimdulI'm a little uncertain of this derivative class for figuring out derivatives and then a different class and interface for each plugin instance. It seems harder to understand. The null fallback is fairly clever though.
I'm really not a fan of this, especially the "maybe we call a static method maybe we call a normal method" runtime on the calling side.
Kris and I are going to discuss this more tomorrow but just wanted to jot down some notes on looking over this patch.
Comment #18
neclimdulmerlin, eclipse and I had a call today and we decided supporting both static and instantiated methods is making things a bit of a mess. Eclipse conceded(perhaps a bit reluctantly) that using statics means we can not easily use any sort of constructor or injection if we go with static methods. It'd require a soft options array sort of argument. (side note, crell will also be happy)
So action items, look at at effulgentsia's last patch and see if we can't merge it into eclipse's earlier patch. Maybe using some of the branch I was working on if it makes sense.
Timeframe, we'll see how the weekend goes and if I'm able to review, if not eclipse and I will try and work on it during the week, worst case eclipse will probably work on it Friday during his SCOTCH time.
Comment #19
effulgentsia commentedOk, here's #16 with everything related to StaticDerivativeInterface removed.
I changed some terminology in this patch's DerivativeDiscovery class to make it even more confusing to draw attention to it: a really ugly name for its protected function:
getPluginSpecificDerivativeDiscovery().So basically, we have:
-
Drupal\Component\Plugin\Derivative\DerivativeInterface: the interface that needs to be implemented by the $pluginDefinition['derivative'] class. This class deals with returning derivatives of a particular plugin. It doesn't trouble itself with splitting or joining on colon.-
Drupal\Component\Plugin\Discovery\DerivativeDiscoveryInterface: the interface that needs to be implemented by an object for merging base plugins with derivative plugins. I don't think it's technically a "mediator" design pattern, but I think of it as kind of mediating between the DiscoveryInterface object and the DerivativeInterface object, enabling those two to be fully decoupled.-
Drupal\Component\Plugin\Discovery\DerivativeDiscovery: the 1 class that provides an implementation of DerivativeDiscoveryInterface we expect to be suitable for 99% of plugin types that want to support derivative plugins.While I think the names of all of the above could be improved to help clarify the relationships, I think the first question to settle is whether this architecture is what we want at all (no use brainstorming better names if we don't like the pattern).
The alternative is what neclimdul has in plugins-derivatives, where instead of a separate DerivativeDiscovery class, that logic is put inside DiscoveryAbstract and all Discovery classes inherit from that. That cuts down on the number of classes that need to be named, but I'm concerned that it makes some arbitrary logic (e.g.,
$derivativePluginId = $basePluginId . ':' . $derivativeId;) not easily swappable (for example, if for whatever weird reason, I want my plugin type to combine base plugin ids and derivative ids differently, I now need to subclass ConfigDiscovery or InfoHookDiscovery into SlightlyDifferentConfigDiscovery or SlightlyDifferentInfoHookDiscovery just to override the logic inherited from DiscoveryAbstract). If we're willing to accept this limitation due to this being an edge use-case, I won't object to us going back to the DiscoveryAbstract approach, but it stands out to me as unnecessary coupling.Comment #20
effulgentsia commentedComment #21
sunSorry, I totally wanted to post a more in-depth review here (some days ago), but only got this far. Got totally distracted with CMI and Testing system work. :-/ I'm not sure whether this helps in any way, but well...:
Is there any reason for why you guys chose to go with the name "derivatives" instead of "variants", which sounds much more human and pronounceable to me? At least for me, as a non-native English speaker, and as a non-native OO speaker, that would be much more clear.
It's no clear to me how a variant/derivative of one base plugin could ever be re-used for another base plugin, and why we actively try to support that.
No idea what this means, needs more context.
Comment #22
effulgentsia commentedIn IRC, neclimdul said that even though the DerivativeDiscovery mediator might be more architecturally pure, he felt it's not worth the added mental strain of yet another hard to name object/class in the whole system. In practice, the two assumptions it makes (combining base id and derivative id with a colon, and finding the plugin's derivative fetching class in $definition['derivative']) rarely need to be overridden, and in the rare cases where they do, subclassing the top-level Discovery class isn't that big a deal.
So, here's a patch that's closer to neclimdul's original architecture of using an abstract base class, which I named DerivativeAwareDiscovery.
The derivative ids can be reused (i.e., have local scope). Block plugin "foo" can have derivatives "x" and "y", and block plugin "bar" can have derivatives "x" and "z". The discovery system translates this into "foo:x", "foo:y", "bar:x", and "bar:z".
Comment #23
neclimdulOk, spent the day reviewing this and I like it. I'm not sure the fetcher helper buys us a lot but it probably doesn't hurt so I didn't touch it. Did some cleanups and a couple tweaks:
If no one has any objections I'll commit it and we'll put this to rest at long last.
Comment #24
neclimduloh, the split encode/decode logic has a slightly cheaper set of string functions when dealing with derivative id's(from some goofy synthetic benchmarks). they where generally close though and this seems easier to read.
Comment #25
effulgentsia commentedThanks!
Comment #26
neclimdulI can't express how thankful I am for driving this home effulgentsia.
Comment #27
webchickYAYYYY!! Great job, guys!!
Comment #28
eclipsegc commented+1000000
Please link the core issue that will follow this patch (or whatever) here.
Comment #29
effulgentsia commented#1497366: Introduce Plugin System to Core is the core issue where neclimdul will post an updated patch. Last one there is from too long ago. IMO, we should get these major/critical issues in first, though perhaps the documentation one can happen in stages so as not to delay getting the code itself in front of core reviewers.