Problem/Motivation
Ideally, the migrate source plugin should be nothing else but an iterator over the source data. We have piled a lot of code into SourcePluginBase (which previously was a Source wrapper though) especially next().
Proposed resolution
We do two things in prepareRow // next: add additional additional data and filter rows. So let's add two new plugin types and make source into a single pipeline (process is multiple pipelines, in comparison). The first step is always an iterator plugin exactly as now. The plugin would also define fields and ids as now. Instead of Iterator I'd have it implement IteratorAggregate . Note how little most (all?) source plugins would need to change.
And then we would have new plugin types: one for adding data to the source and another for filtering data. The current filter plugins are: id, highwater, status and changed. We could add an empty plugin as well, for example to immediately skip disabled blocks. This would be so much cleaner than hook_prepare_row, gosh.
It is an interesting question where do we put the invocation logic for this -- I guess MigrateExecutable would do. It's not a lot of code, after all.
For backwards compatibility, the iterator plugin will be inspected for implementing the old MigrateSourceInterface and if so, then its prepareRow will be treated as an addition plugin.
New syntax:
source:
iterator: d7_node
add:
-
plugin: d7_fields
filter:
-
plugin: highwater
Remaining tasks
Code this. It's just reshuffling existing code.
User interface changes
None.
API changes
We add a NewMigrateSourceInterface which will only be an iterator (and fields and id) and two new plugin types.
Data model changes
None.
Original issue statement
Ideally, migration source plugins (which control iteration over and delivery of data from a data store) should be usable by themselves, without a containing migration - unfortunately, MigratePluginBase requires a MigrationInterface argument. We already have concrete use cases for this - #2530030: Create the migrate builder plugin type is forced to construct a dummy migration to use a source plugin, and in contrib we want to bring the D7 drush migrate-analyze command (doing data analysis on source data) forward.
This is an API breaker, and there are already source plugins in the wild being developed, so we recognize it may need to be postponed until 9.0, but let's at least get this on the table.
In a quick scan of SourcePluginBase, I identified these uses of the migration:
- idlist handling - I'm hoping that event support (particularly a prepareRow event) will mean we can take this out of core entirely and let the contrib tools handle it themselves. Done
- Highwater marks - We could have distinct APIs specifically for dealing with highwater marks, rather than going through the migration class.
- Id map plugins - This is an unnecessary coupling in itself, but thoroughly embedded. At least as a first pass we could pass the id map plugin instead of the migration class so we can at least decouple those, and deal with source/map decoupling in a separate issue.
- SqlBase also uses the migration in tagging the query - the "migrate_[migration_id]" tag could be addressed with a "query_tag" argument. The migration itself is added as metadata to the query itself - we should look into what use cases there are for this. If it is necessary, the containing migration could do a query alter to add it.
We also should scan specific source plugins for any other uses of the migration.
Comment | File | Size | Author |
---|---|---|---|
#16 | interdiff.txt | 853 bytes | dawehner |
#16 | 2543552-16.patch | 23.76 KB | dawehner |
#15 | 2543552-15.patch | 21.79 KB | dawehner |
Comments
Comment #1
mikeryanComment #2
mikeryanNot realistic in the 8.x timeframe.
Comment #3
catchMoving back to 8.x, I don't see anything here that couldn't theoretically be done with a backwards compatibility layer.
Comment #4
chx CreditAttribution: chx as a volunteer commentedComment #5
chx CreditAttribution: chx as a volunteer commentedComment #6
benjy CreditAttribution: benjy at PreviousNext commentedThe proposal sounds good to me, I'm sure I've discussed this previously with chx. Not sure it's a Migrate Critical though, thought we were using that tag to track issues we needed in for Migrate to be stable?
Comment #7
chx CreditAttribution: chx at Migrate Rocks commented> Not sure it's a Migrate Critical though, thought we were using that tag to track issues we needed in for Migrate to be stable?
I'd rather not have the current migrate source structure marked stable.
Comment #8
mikeryanComment #9
chx CreditAttribution: chx as a volunteer commentedComment #10
chx CreditAttribution: chx as a volunteer commentedComment #11
chx CreditAttribution: chx at Migrate Rocks commentedWorking on this. Won't be quick. Want to help? It's in the sandbox, branch is migrate-next. If you need commit privileges just ask although most of the usual suspects already have.
Comment #13
alexpottHow does
align with #7. If we can implement a BC layer then surely the core source plugins don't have to change?
Comment #14
chx CreditAttribution: chx at Migrate Rocks commentedActually, as it shows, not working on it. I do not have the mental fortitude required any more to pour untold amount of hours into core just because it'd be nicer some time in the future. Still, this hopefully needs to get done. By someone else.
Comment #15
dawehnerHere is some form of start we (chx, dawehner) worked together.
Comment #16
dawehnerSome progress.
Comment #17
alexpottDiscussed with @benjy. We agreed that this is a good idea and certain improves the migrate system. We also agreed that the current solution and problem scope is not on the critical path to getting migrate stable. We also agreed that this improvement could go into 8.x if it has a BC layer and we would deprecate the current behaviour.
@chx thanks for posting the issue, working on migrate, and pouring untold amounts of hours into core. I hope this does happen in 8.x it is just that getting migrate stable and all the existing bugs fixed is more important than good architectural improvements at this point.
@dawehner I hope this comment does not discourage you from working on this because if you can conjure up a BC layer it'd be great :)
Comment #18
chx CreditAttribution: chx at Migrate Rocks commentedWhile I have my doubts whether it's possible to get migrate stable without this patch, here are some problems:
Comment #19
alexpott@chx - just looking at point 3 - well nothing in core is using hook_migrate_prepare_row() so if there's no use-case in contrib atm we could remove that in a very small patch no?
Comment #20
alexpottI spoke to @mikeryan and he said that migrate_plus exposes this as an event and custom migrations he has worked on use it. So if we remove it we'd need an adequate replacement. @chx what do you mean by horrific - hook_module_implements_alter() is horrific but otoh very powerful when you need it. Not all hooks are designed to be safe. Maybe they should be but we certainly are not there in D8.
Comment #21
chx CreditAttribution: chx at Migrate Rocks commentedThe problem is not hook vs event but the double role of hook_prepare_row of adding AND filtering and the filtering is really badly obscure.
And no, you can't remove it, many custom site migrations (like mine) use it to add additional data to the existing core plugins. Would need to extend the core plugin and write mine for each, such bother.
And I do not know how to express this in a polite way but anything in migrate_plus and migrate_tools should not steer core. Quite the contrary and even that is refused.
Comment #22
dawehner@chx
Please be calm, see http://xjmdrupal.org/blog/someone-worked-hard-on-it
Comment #23
mikeryanMigrate API is now beta, and it's hard to see how to do a BC layer for this. High priority when getting into refactoring for D9, but for now the current source plugin architecture works fine for our needs.
Comment #29
heddnI think this issue has served its purpose during the life span of D8. In D9 we might look into this more, but it will probably do things in entirely new and different ways than what we've discussed in here. And most likely start in a sandbox/contrib project. So for now, marking this closed.