Problem/Motivation

Our site, for better or worse, has 3000+ beans--many of which use field collections. Modules like Panelizer and Block Reference invoke hook_block_info() on every uncached page. We are experiencing major performance issues because even with memcache and entity_cache installed, bean_block_info() spends a LOT of time just to provide the bean delta, title and CACHE_ constant.

Proposed resolution

Add persistent caching to bean_block_info() to avoid loading all beans at run-time when using panels.

Note that Drupal 8 block content entities suffer from a similar issue:
https://github.com/vasi/block_access_records

Remaining tasks

User interface changes

API changes

Data model changes

Comments

krlucas created an issue. See original summary.

sylus’s picture

Issue summary: View changes
StatusFileSize
new398.11 KB

see next post.

sylus’s picture

StatusFileSize
new357.13 KB

I saw this too when profiling and gave the patch a try. I attached what got reported in xhgui + xhprof between comparison runs with patch not applied, then applied.

xhgui

sylus’s picture

Issue summary: View changes
sylus’s picture

Would love to get a opinion of the bean maintainer if this suffices?

damienmckenna’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, bean-optimize-bean_block_info.patch, failed testing.

sylus’s picture

I fail to see what is causing the tests to break but they have been passing as of a week ago.

krlucas’s picture

@sylus

I also don't know exactly why the patch is failing but per my original description the patch completely sidesteps the bean-as-ctools-plugin API enhancements that were semi-recently added to the Bean module API. Getting this patch to a committable state probably requires enhancing that API.

Your profiling results are nonetheless extremely valuable!

joseph.olstad’s picture

Could the difference be that the testbot is now using Drupal core 7.44 ?

last successful pass of this patch was June 7th prior to the release of 7.44.

most recent pass, June 7, 2016 - 11:27

fabianx’s picture

The best idea likely is to cache the hook_block_info() information as the array is sparsely populated anyway and only needs to be expired if a bean is saved (inserted / updated). It could automatically be expired when the _block_hash function is called - similar to how block_cache_alter() achieves the block altering, the cache could be expired then.

joseph.olstad’s picture

Status: Needs work » Needs review

Just triggering test bot
HEAD is passing

Status: Needs review » Needs work

The last submitted patch, bean-optimize-bean_block_info.patch, failed testing.

fabianx’s picture

Status: Needs work » Needs review
StatusFileSize
new1.08 KB

And here we go, attached patch works like a charm for me even with many many beans and saves 250 ms per page load for me (out of 1.5 seconds).

The real modules to fix here is ctools content types though and context and ...

It is a real problem how many modules re-implement listing and rendering of blocks (and not using core blocks tables for it - even if block module is enabled).

Status: Needs review » Needs work

The last submitted patch, 14: bean_unnecessarily-2734693-12.patch, failed testing.

fabianx’s picture

Priority: Major » Critical
Issue tags: +Needs reroll
joseph.olstad’s picture

Status: Needs work » Needs review
StatusFileSize
new979 bytes

hip shot

joseph.olstad’s picture

Issue tags: -Needs reroll
joseph.olstad’s picture

I wonder if the @krlucas patch and patch #17 could be combined for an even greater performance gain.

However I'd be inclined to RTBC #17 and get #17 committed as-is and open a new followup issue for investigating further possible improvements in performance using a rerolled @krlucas patch

joseph.olstad’s picture

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community

see comment #19 , to me this seems like something that should urgently be done. Pet peeve on unnecessary lag.

krlucas’s picture

@joseph.olstad

Yeah I was about to mark this as needs work because while @fabianx's caching helps n+1 calls to hook_block_info it doesn't really solve the "unnecessarily" part of the issue. AFAIK there are very few places in core that call hook_block_info EXCEPT after a block (or bean) has been saved. That first call too bean_block_info after saving a bean is still going to be really, really slow (on a site with a lot of beans) for no good reason. In my use case, the real burden of this issue fell on content authors, making their job unbearable.

That said, if we want to add this caching I won't object as long as a follow-up is created to address the real issue.

joseph.olstad’s picture

well if its not going to cause another 7 months of delay perhaps we should set this back to needs work then and combine your @krlucas patch with the patch #17

joseph.olstad’s picture

Status: Reviewed & tested by the community » Needs work
fabianx’s picture

Status: Needs work » Reviewed & tested by the community

Definitely not. Lets discuss in a follow-up, because it is a quite complex issue:

The problem is that the bean adminTitle can be arbitrarily defined at run-time and also the cacheLevel property can be defined to something else than CACHE_PER_ROLE, e.g. the original patch would create problems on real sites.

Now we could "cache" those per bean e.g. by adding new properties to the database table and hope that no-one sets the adminTitle / cacheLevel dynamically.

Then the approach could in fact work, but its way more complicated than to add caching for now.

fabianx’s picture

Also e.g. as soon as you use beans with panels instead of core block module, hook_block_info() is called uncached on every page load.

fabianx’s picture

Title: Bean unnecessarily fully loads all bean entities on hook_block_info » Add persistent caching to bean_block_info() to avoid loading all beans at run-time when using panels / ctools content type block plugin
Issue summary: View changes
joseph.olstad’s picture

@Fabianx , nice work thanks. Lets get this in!

damienmckenna’s picture

Title: Add persistent caching to bean_block_info() to avoid loading all beans at run-time when using panels / ctools content type block plugin » Add persistent caching to bean_block_info() to avoid loading all beans at run-time when using Panels / CTools content type block plugin
Status: Reviewed & tested by the community » Fixed
Parent issue: » #2840282: Plan for Bean 7.x-1.12 release

Committed. Thanks.

joseph.olstad’s picture

For the record, credit should be to @Fabianx as author, I merely re-rolled it due to a broken path in the patch. Thanks @Fabianx and @DamienMckenna.

  • DamienMcKenna committed 7326cd9 on 7.x-1.x authored by Fabianx
    Issue #2734693 by joseph.olstad, Fabianx, krlucas, sylus: Add persistent...
  • DamienMcKenna committed c530d4b on 7.x-1.x
    Revert "Issue #2734693 by joseph.olstad, Fabianx, krlucas, sylus: Add...
damienmckenna’s picture

Thanks for the clarification, joseph.olstad, I've recommitted the patch and gave Fabianx the credit.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.