Closed (fixed)
Project:
Drupal 8 Blocks Everywhere
Component:
Plugins
Priority:
Major
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
2 Apr 2012 at 17:46 UTC
Updated:
19 Jun 2012 at 03:21 UTC
Jump to comment: Most recent file
Pretty simple concept really. Hooks are still a thing in Drupal and having an implementation that uses hooks for discovery would be useful for comprehension and possibly some cases of plugins that run high in the module space.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | plugins-hook-discovery-22.patch | 10.68 KB | effulgentsia |
| #22 | interdiff.txt | 4.91 KB | effulgentsia |
| #20 | plugins-hook-discovery-20.patch | 8.61 KB | effulgentsia |
| #20 | interdiff.txt | 1.75 KB | effulgentsia |
| #19 | plugins-hook-discovery-19.patch | 8.64 KB | effulgentsia |
Comments
Comment #1
effulgentsia commentedHere ya go. This is rebased against plugins-kernel with #1529162-2: Decouple plugin type discovery from plugin discovery applied, so make sure to apply that patch first if you want to commit or review in context.
Comment #2
neclimdulI've already got one written and am working on a reflection based discovery. I've just been holding off pushing it till we sort out what is happening to discovery
Comment #3
effulgentsia commentedHere's a reroll for plugins-next. I have no objection at all with you committing your version instead of this, but I think we're all settled on discovery, so I don't think there's a reason for this issue to stay postponed.
Incidentally, I did a search on HEAD for how many hook_*_info() hooks we have in core, and it's a couple dozen: more than I realized. So once a plugin system is in core, we'll have an opportunity to use it a lot: tokens, filters, language types, language negotiation, openid, archiver, updater, and more.
Comment #4
yched commentedI think "plugin" currently designates "an instantiated plugin object. This var stores $definitions (method name is getPluginDefinition(), for that matter).
This assumes all cache entries will live in the same cache bin (the main 'cache' bin, currently) ? "All info hooks in the same bin for all plugin types" might be good enough, but then should this be 'cache', or some dedicated 'cache_plugin' ?
Related : how can outside code trigger a cache refresh ? Persistent cache is easy (bin is hardcoded and cid is known by the plugin type), but the HookDiscovery class also acts as a static cache. In the current architecture, clearing that one means means ditching the PluginType object stored in drupal_object(), which is not doable right now.
Or : PluginTypeInterface needs a resetDiscovery() method ?
I like the before_alter callback, since I'll need to fill-in missing properties on each definition.
One thing that the current code doesn't allow, is tracking which module provides which definition (I need this for 'field type' plugins). This information is lost after module_invoke_all(), this would rather require something like :
Comment #5
neclimdulreally we need default logic for all plugin types. I don't know that this has to happen in this sort of process logic though. The type could handle it after the fact.
Comment #6
yched commented+1 for the $this->defaults code that went got added in plugins-next.
I guess this makes the 'before_alter' property moot.
Comment #7
yched commentedUpdated patch on top of #1540206: Allow self inspection on instantiated plugin objects (the patch in there fixes processPluginDefinition()).
Fixes most my remarks in #4 :
- Adds $definition['module'] = $module; in HookDiscovery::getPluginDefinitions()
- Adds $plugin_id as an argument for processPluginDefinition() (to allow
$definition['name'] = $plugin_id)- Removes the 'before_alter' callback; moves the ksort on image effects, does it on the calling side in the image effects UI
- Adds a HookDiscovery::clear() to flush persistent and static caches.
Right now as a method on the Discovery class only and without a proxy method on the PluginType, it's not accessible from the outside. Not sure what to do with that yet. Adding a clearPluginDefinitions() method on the PluginType makes no sense for the current other discovery classes, that do not cache anything - although they should ?
Comment #8
effulgentsia commentedMaybe we should move the ksort() into image_effect_definitions()? In a follow-up, we'll need to figure out if we want HookDiscovery to support a sort() callback, or a more generic beforeAlter() or afterAlter() callback, since processDefinition() runs on a single definition and therefore can't sort definitions. But that follow-up can happen after an initial core patch lands.
There's no drupal_object() any more.
I think for now, we can leave it a per-discovery-class and per-type-class decision for if and how to deal with internal cache clearing. Perhaps in a follow-up we can discuss whether to add an interface for or extend existing interfaces to standardize cache clearing. In any case, good call on adding HookDiscovery::clear().
Comment #9
yched commentedThe ksort IMO has no reason whatsoever to be part of image_effect_definitions(). It's only used for the order of options in the UI select dropdown (arguably, IMO - I don't see how sorting on machine name helps UX). So I'd say it belongs the the corresponding UI code.
I don't think that we should support the idea that the list of implementations of a given plugin type has one good natural order. Ordering, if relevant, is ad-hoc IMO, not inherent to the list itself.
Not sure we have other cases for full-list-only massaging of the definitions ?
for now, we can leave it a per-discovery-class and per-type-class decision for if and how to deal with internal cache clearingAgreed, but currently there is no way to call HookDiscovery::clear() from the outside. PluginType doesn't let you access the discovery directly, and clear() is not part of PluginTypeInterface.
Comment #10
effulgentsia commentedYep. Good reasoning.
Yep. I also agree. Or in any case, the plugin type can provide sort function(s) as appropriate. So, we can have a
Drupal\image\Effect::sort()function orDrupal\image\Effect::sortByName()/Drupal\image\Effect::sortBySomethingElse()functions. We don't need to add this to this patch, just agreeing that it's not the plugin system's job to deal with sorting.What I mean by per-type-class decision is Drupal\image\Effect can provide a clear() method that calls $this->discovery->clear(). If the "outside" wants to clear image effect caches, it knows it's working with a Drupal\image\Effect object, not just a PluginTypeInterface, so it can call that method. Eventually, I suspect we'll want to add something to PluginType and/or PluginTypeInterface, but I'd rather not derail on that, and instead come back to it once we have some core subsystems converted so we can see where there's redundancies to optimize.
Comment #11
yched commentedWorks for me - this might mean that some surrounding code gets type-hinted as Drupal\image\Effect rather than PluginInterface, though, which violates some standards.
Although those standards are probably not strict ones; at some point, you have to know you work with a specific plugin type - and the indirection between [$scope, $type] and PluginTypeClass was abandoned, so a plugin type *is* a given class.
So, fine :-)
Then it means every plugin type that uses HookDiscovery must implement a clear() method on its own ?
Comment #12
neclimdulMarking this major. ConfigDiscovery is now removed so there is not functioning core discovery(static could be used in a pinch) and it would be really good to have this to help understand how the system works since hooks are so familiar.
We're going to need some love and rerolls with the other commits that went in today.
Comment #13
effulgentsia commentedOn it.
Comment #14
effulgentsia commentedComment #15
effulgentsia commentedThis decouples from #1540206: Allow self inspection on instantiated plugin objects. yched's points in both these issues are valid, but we can start with this, and improve in the other issue. I don't have image style tests passing though, so still troubleshooting that.
Comment #16
effulgentsia commentedYay. "Image styles and effects UI configuration" tests pass.
Comment #17
neclimdulI was about to bounce back that the tests weren't passing but turns out it was just an odd ball core bug(#1614292: image_style_delete_form doesn't take form_state by reference).
Just so they're documented my reactions went something like "Do we need the cache? This looks reasonable and flexible and we can replace it with the "cache any discovery" system we've discussed some other time. Do we need to use the DI Container? Meh, it works just fine and avoids a global pretty effectively."
I'm marking this RTBC just to let it settle a bit and let my subconscious mull on it but seems like its good to go. Thanks!
Comment #18
neclimdulJust noticed this, when ever I see two module_* functions next to each other I always question it. They tend to double call module_hook() and I suspect we could replace this with call_user_func is we're micro-optimizing.
If someone feels strongly in favor of that they can reroll but behind the cache it shouldn't matter terribly.
Comment #19
effulgentsia commentedComment #20
effulgentsia commentedIf you prefer this one, commit this one. If you prefer #19, commit that one. Your choice.
Comment #21
effulgentsia commentedI forgot to unassign myself from this when I posted a working patch in #16. Better late than never.
Comment #22
effulgentsia commentedInspired by #1613638: Use decoration instead of a base class for derivative discovery, here's an implementation of cache as decorator. Leaving at RTBC, because if you don't like this, you can commit #19 or #20 instead.
Comment #23
neclimdulLast night: Man Effulgentsia is a patch demon. When I wake up tomorrow I'll commit that hook patch.
This morning: Oh look, he added that CacheDecorator I was going to follow up with!
Thanks for the great work everyone! Fixed!
Comment #24
neclimdulComment #25
neclimdulSo... For some reason but in php 5.3 on the testbot(see main plugin issue) and on my work dev box some image tests are failing. They don't seem to be failing in php 5.4 or are silently which makes no sense. Best I can tell, when requesting a processed image sometimes image.effects.inc isn't loaded and the module_implements doesn't show any hooks.
This doesn't actually make any sense to me but the hook definitely isn't getting called and adding a require at the top of image.module to always include image.effects.inc fixes it.
Somewhat related, the warnings that this failure is causing makes it looks like we need to be more explicit about the return of getPluginDefinition() when the plugin doesn't exist because we're getting some weird warnings.
Comment #26
neclimdulSo... tests are failing because of #1617208: After kernel patch, module_hook_info() returns an empty array when called by load callback, access callback, or hook_init(). nothing to do with us. Don't know why php 5.4 works but what ever.