This is kind of a weird one, so bear with me.

We recently updated one of our sites to 7.50 and noticed that in some circumstances a cache clear can cause (some) Field API fields to fail to display. It's weirdly intermittent but seems to only happen using "drush cc all" from the command line, though not always; clearing the cache via the HTTP front end seems to work properly. Unfortunately our in-house cron process uses drush instead of an HTTP request, so this isn't something we can just remember not to do.

What actually seems to happen - after crawling through the code - is that when the field info class is rebuilding its cache for the first time, within the prepareInstanceDisplay() method, field_info_formatter_types() returns nothing. (It's called up to twice, once to load the specific formatter chosen for the field instance being displayed, and if that fails, once more for the field type's default formatter.) The module assumes a formatter definition has been returned by at least one of these calls, and proceeds to assign its 'module' property to the $display array. Having a null 'module' means the field fails to display. (As a knock-on effect it confuses Features, which apparently uses the cached field data in preference to what's actually stored in the database, but that's more of a symptom.)

Drilling down into field_info_formatter_types() it looks like _field_info_collate_types() is failing to build the full field types info set. Placing DSM calls at the start and both ends of this function, it seems that _field_info_collate_types() is being called a bunch of times before the first call has finished - I'm getting two "starting" messages in a row, and a whole slew more "starting" and "finishing" messages before - a good long way down the page - a dump confirming the built cache data finally appears (right before two "finishing" messages in a row). This to me suggests it is being called asynchronously, with dozens of field_info_formatter_types() calls working off the unfinished $info static variable before the first call finishes. That bad data is then cached in the FieldInfo::getInstances()/FieldInfo::getBundleInstances() caches, and used for subsequent renders.

For the time being I've thrown an IF statement around the assignment, so in the event of finding no definitions it'll stick with the 'module' data that's already being passed in with the $display settings. I'm don't know why this is even necessary if we have a perfectly usable 'module' set already, but I assume there's a good reason for it?

Anyway. I've attached a patch for this though obviously it would be better to prevent the bad data being used in the first place.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

kingandy created an issue. See original summary.

kingandy’s picture

Issue summary: View changes
kingandy’s picture

hm, version field fails on edit, interesting

ankitgarg’s picture

Status: Needs work » Needs review
FileSize
635 bytes

Patch Refix.

Version: 7.5 » 7.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.