system_update_8402 adds the revision_translation_affected field to all entity types. Unfortunately, it conflicts with the Media Entity update path because Media Entity 2.x defines its entity types dynamically, in hook_entity_type_build(). If system_update_8402 is run before the module hook implementation cache has been cleared, the system never knows that the Media entity type exists, and media entities do not receive the revision_translation_affected field. This can break a bunch of stuff further down the line.
Proposed resolution
Add an update hook before media_entity_update_8201 to clear the hook implementation cache, and then implement hook_update_dependencies() to force that hook to run before system_update_8402. This will guarantee that media entities receive the revision_translation_affected field.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | interdiff-2916788-3-9.txt | 400 bytes | phenaproxima |
| #9 | 2916788-9.patch | 2.72 KB | phenaproxima |
| #3 | 2916788-3.patch | 2.67 KB | phenaproxima |
Comments
Comment #2
phenaproximaRe-titled, and tagged.
Comment #3
phenaproximaAnd, the patch.
Comment #4
seanbOk so I think this will probably need some tests to make sure it works. Discussed with phenaproxima on IRC. For now we'll just do some manual testing. Before we mark the upgrade path stable we should create more tests for scenario's like this in #2916821: Improve automated tests of Media Entity upgrade path to Media core.
Marking for manual testing.
Comment #5
phenaproximaHere's how to test this:
Comment #6
phenaproximaBumping status to critical, since this blocks the update path.
Comment #7
seanbThis doesn't seem to work for me? The update order runs as expected with the patch. So that part works as expected. When I tried to see what's going on, it seems that when installing the media module in
media_entity_update_8201()line 358, the key/value entity.definitions.installed|media.field_storage_definitions is updated. This makes the checkif (!$definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id))insystem_update_8402()fail and as a result the field storage definition forrevision_affected_translationis not installed.We could add our own update hook to check if the column actually exists for media, and force
installFieldStorageDefinition(), but maybe there is another way?Comment #8
phenaproximaThis bug is tricky to reproduce, because it is non-deterministic in nature. It depends on updates running in the wrong order, which is basically impossible to guarantee.
I just explained this to @seanB over the phone, but I want to record it here for future reference.
Here's the thing: in order to prevent things from breaking during the update process, the system must, at all times, be aware of the media and media_bundle entity types -- at least until core Media is installed, since it canonically defines those entity types. This is why the 2.x version of Media Entity implements hook_entity_type_build(). It's a shim to make sure the system always knows that media and media bundle entities exist, even when core Media is not installed.
Now: along comes system_update_8402, which collects all entity type definitions in order to determine which ones need the revision_translation_affected field added. hook_entity_type_build() is invoked as part of this process. However, because the hook has just been added to Media Entity's code base, the module handler is not aware that Media Entity now implements hook_entity_type_build(), because it is relying on a stale hook implementation cache! So media_entity_entity_type_build() is never called, and the system never knows that the media entity type exists. Therefore, it does not add the revision_translation_affected field to media entities, and things blow up later. You can get around this problem by clearing all caches before running database updates, but we most definitely cannot guarantee that users will remember to do that.
So the only real fix here is to add an additional update hook which runs before system_update_8204 and guarantees that the hook implementation cache is primed with the latest information.
That's what this patch does. It adds media_entity_update_8200, which clears the implementation cache, and then defines a dependency that forces it to run before system_update_8204.
What makes this so hard to verify is the fact that, absent a dependency graph, updates run in a non-deterministic order. So it is entirely possible that, even without the dependency, media_entity_update_8200 would run before system_update_8204, thus accidentally avoiding this problem. That's not good enough: we need to be damn sure that media_entity_update_8200 runs before system_update_8204.
Comment #9
phenaproximaAfter discussion with @seanB on IRC, we decided it would be wise to add a hard dependency that forces media_entity_update_8201 to run after system_update_8402, for the reasons mentioned in #7.
Comment #10
seanbYep, that does it!
Comment #12
phenaproximaCommitted and pushed. Thanks!