Problem/Motivation

I have a serious problem at the moment. There is a seach view (search api solr) that is set up and works great. when i enable the metatag views submodule i have the following behavior. a keyword is entered in the search input field, the view outputs results. when the same page is refreshed with the same keyword i get an error message in the frontend out of memory. no matter how much ram i free, 1gb, 2gb, 6gb it stays with the same error. this doesn't always happen though and i don't always have a logged error message in the log.

the search view itself has no cache tag, because of fulltext search they are disabled. but even with enabled cache tags (normal or via search-api) it remains the same behavior.

attached the error from the log.
anyone ideas?

Error: Call to a member function getCurrentPage() on null in Drupal\views\Plugin\views\cache\CachePluginBase->generateResultsKey() (line 219 of /var/www/html/docroot/core/modules/views/src/Plugin/views/cache/CachePluginBase.php)
#0 /var/www/html/docroot/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php(92): Drupal\views\Plugin\views\cache\CachePluginBase->generateResultsKey()
#1 /var/www/html/docroot/core/modules/views/src/ViewExecutable.php(1419): Drupal\metatag_views\MetatagViewsCacheWrapper->cacheGet('results')
#2 /var/www/html/docroot/core/modules/views/src/ViewExecutable.php(1454): Drupal\views\ViewExecutable->execute(NULL)
#3 /var/www/html/docroot/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(2460): Drupal\views\ViewExecutable->render()
#4 /var/www/html/docroot/core/modules/views/src/ViewExecutable.php(1662): Drupal\views\Plugin\views\display\DisplayPluginBase->preview()
#5 /var/www/html/docroot/core/modules/views_ui/src/ViewUI.php(602): Drupal\views\ViewExecutable->preview('search_results', Array)
#6 /var/www/html/docroot/core/modules/views_ui/src/ViewPreviewForm.php(62): Drupal\views_ui\ViewUI->renderPreview('search_results', Array)
#7 /var/www/html/docroot/core/lib/Drupal/Core/Entity/EntityForm.php(106): Drupal\views_ui\ViewPreviewForm->form(Array, Object(Drupal\Core\Form\FormState))
#8 /var/www/html/docroot/core/modules/views_ui/src/ViewFormBase.php(41): Drupal\Core\Entity\EntityForm->buildForm(Array, Object(Drupal\Core\Form\FormState))
#9 [internal function]: Drupal\views_ui\ViewFormBase->buildForm(Array, Object(Drupal\Core\Form\FormState), 'search_results')
#10 /var/www/html/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(532): call_user_func_array(Array, Array)
#11 /var/www/html/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(371): Drupal\Core\Form\FormBuilder->retrieveForm('view_preview_fo...', Object(Drupal\Core\Form\FormState))
#12 /var/www/html/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(629): Drupal\Core\Form\FormBuilder->rebuildForm('view_preview_fo...', Object(Drupal\Core\Form\FormState), Array)
#13 /var/www/html/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(321): Drupal\Core\Form\FormBuilder->processForm('view_preview_fo...', Array, Object(Drupal\Core\Form\FormState))
#14 /var/www/html/docroot/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\views_ui\ViewPreviewForm), Object(Drupal\Core\Form\FormState))
#15 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#16 /var/www/html/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#17 /var/www/html/docroot/core/lib/Drupal/Core/Render/Renderer.php(578): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#18 /var/www/html/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#19 /var/www/html/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#20 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#21 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#22 /var/www/html/docroot/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/html/docroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /var/www/html/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /var/www/html/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /var/www/html/docroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /var/www/html/docroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /var/www/html/docroot/modules/contrib/remove_http_headers/src/StackMiddleware/RemoveHttpHeadersMiddleware.php(49): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\remove_http_headers\StackMiddleware\RemoveHttpHeadersMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /var/www/html/docroot/core/lib/Drupal/Core/DrupalKernel.php(717): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#31 /var/www/html/docroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#32 {main}

Steps to reproduce

Proposed resolution

Temporary workaround for site experiencing this problem in the wild: Roll back to metatag 8.x-1.6 until a solution is available.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

zcht created an issue. See original summary.

zcht’s picture

While trying to reproduce the problem under different circumstances, I found a new hint.

at are also once two times the following files as error were displayed.

Deprecated: assert(): Calling assert() with a string argument is deprecated in /var/www/html/docroot/core/lib/Drupal/Core/Cache/Context/ContextCacheKeys.php on line 26

Deprecated: assert(): Calling assert() with a string argument is deprecated in /var/www/html/docroot/core/lib/Drupal/Core/Cache/CacheableMetadata.php on line 127

Attached is the error output.

Edit: For brevity, I moved the backtrace output to a txt file attached to comment #27. - @dww

oxy86’s picture

I get the same error on two different D9.3 websites (both migrated from D7). In my case, though, the error occurs when the metatag_views submodule is enabled, and I click on the preview button in any view. The preview does not work and I get the error:

2021/12/23 16:48:03 [error] 1494#1494: *20076595 FastCGI sent in stderr: "PHP message: Error: Call to a member function getCurrentPage() on null in /var/www/supersyntages.gr/web/core/modules/views/src/Plugin/views/cache/CachePluginBase.php on line 220 #0 /var/www/supersyntages.gr/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php(92): Drupal\views\Plugin\views\cache\CachePluginBase->generateResultsKey()
#1 /var/www/supersyntages.gr/web/core/modules/views/src/ViewExecutable.php(1419): Drupal\metatag_views\MetatagViewsCacheWrapper->cacheGet('results')
#2 /var/www/supersyntages.gr/web/core/modules/views/src/ViewExecutable.php(1454): Drupal\views\ViewExecutable->execute(NULL)
#3 /var/www/supersyntages.gr/web/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(2460): Drupal\views\ViewExecutable->render()
#4 /var/www/supersyntages.gr/web/core/modules/views/src/ViewExecutable.php(1662): Drupal\views\Plugin\views\display\DisplayPluginBase->preview()
#5 /var/www/supersyntages.gr/web/core/modules/views_ui/src/ViewU...PHP message: PHP Fatal error:  Uncaught Error: Call to a member function get() on null in /var/www/supersyntages.gr/web/core/lib/Drupal/Core/Session/SessionHandler.php:79
Stack trace:
#0 /var/www/supersyntages.gr/web/core/lib/Drupal/Core/Session/WriteSafeSessionHandler.php(95): Drupal\Core\Session\SessionHandler->write('gpAZowrZD4dgvtd...', '_sf2_attributes...')
#1 /var/www/supersyntages.gr/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php(71): Drupal\Core\Session\WriteSafeSessionHandler->write('gpAZowrZD4dgvtd...', '_sf2_attributes...')
#2 [internal function]: Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy->write('gpAZowrZD4dgvtd...', '_sf2_attributes...')
#3 [internal function]: session_write_close()
#4 {main}
  thrown in /var/www/supersyntages.gr/web/core/lib/Drupal/Core/Session/SessionHandler.php on line 79" while reading response header from upstream, client: 79.130.XXX

Note in my case, the view (page or block) itself does work. Only the preview functionality breaks.

Might this be related to #2952229?

oxy86’s picture

Please note, that by downgrading to 1.16 solved the problem for me:
composer require 'drupal/metatag:1.16'
drush cr.
Now the preview in views works as before.

Eugene Bocharov’s picture

@oxy86 , you could try the patch from https://www.drupal.org/project/metatag/issues/3255547 , it should solve the problem with preview

DamienMcKenna’s picture

oxy86’s picture

Thanks, Eugene. I will test your patch from #3255547 and report results in that issue. Damien, sorry for polluting this issue with extra noise :)

wells’s picture

Title: metatag view submodul makes problems with search view » Out of memory error with metatag_view submodule and Search API view

I am having this issue with Metatag v1.18 + Search API views as well on two different sites. In one case the initial search view loads but will run out of memory for any query (regardless of available memory) and in the other case the initial search view runs out of memory as well. #3255547: Metatag Views breaks Views previews and some Views pages does indeed resolve the preview issue but does not resolve the issue with the regular view.

Reverting to Metatag v1.16 is a workaround and I'll try to follow up with some additional research.

wells’s picture

\Drupal\metatag_views\MetatagViewsCacheWrapper::cacheGet at line 92 seems to get stuck in an infinite loop when I enter a search term in the view. This was introduced in #2952229: Allow Views meta tags to "Use replacement tokens from the first row" (D8) and reminded me that I actually ran in to this issue a while back when I tried to use the patch on that issue. I ultimately could not figure out what was causing it so had to back out the patch (and, of course, forget to follow up and leave feedback on that issue!).

wells’s picture

Further to #9 -- the loop happens because getting the results from the cache unserializes and re-executes the view (see core/modules/views/src/ViewExecutable.php#L2539).

However, if I comment out all of \Drupal\metatag_views\MetatagViewsCacheWrapper::cacheGet then \Drupal\views\Plugin\views\cache\CachePluginBase::cacheGet still causing an out of memory error so the issue doesn't seem to be with \Drupal\metatag_views\MetatagViewsCacheWrapper::cacheGet itself. Maybe something to do with how the cache data is saved?

The bit above isn’t relevant. Just commenting that method out has other Side effects. See further comments.

wells’s picture

Further to #10 -- If I comment out core/modules/views/src/ViewExecutable.php#L2540 (the view re-execution) everything appears to work fine -- the search takes place, the results are correct, and the views data and results are cached and retrievable. I backtracked that behavior a bit because the re-execution seemed odd to me but it goes back six years to #2252763: Views exposed filter form causes enormous form state cache entries (see comment #46). The comment there didn't help me fully understand the need but presumably this would be an issue elsewhere in core if that core change was incorrect in some way. So that seems like a dead end.

wells’s picture

One thing I eventually noticed testing this is that the generated results cache key was always the same regardless of the fulltext search term I used. In my case the search view is configured to use tag-based caching. If I disable that caching everything works as expected. So it seems fair to say that the actual initial issue for me is just that I had tag-based caching enabled for the search view when I should not have (and the problem is just exposed by Metatags v1.18).

@zcht says in the initial issue description that they are seeing this issue while not using tag caching. @zcht could you verify that is the case (i.e. that your view display advanced config has "None" for the "Caching" setting)?

I discovered that despite having the caching for my search view set to "Tag based" nothing was actually being cached because of the fulltext search filter (I'm not sure where or how this actually gets cut off but cache-related breakpoints were not hit when I was testing this). I also noticed that the Search API module provides a "Search API (tag-based)" view caching method that does seem to work fine with Metatag v1.16.

But I do still find myself back to out of memory errors if I use Metatag v1.18 in conjunction with the Search API provided tag-based caching so it seems there is still some incompatibility issue when \Drupal\metatag_views\MetatagViewsCacheWrapper wraps \Drupal\search_api\Plugin\views\cache\SearchApiTagCache and overrides its custom ::cacheSet and ::cacheGet methods (in \Drupal\search_api\Plugin\views\cache\SearchApiCachePluginTrait).

wells’s picture

So this is bizarre -- I created an environment to confirm this issue is not specific to anything about my (or the original reporter's) setup other than the module combination and configurations: https://github.com/CascadePublicMedia/metatag-3245876. Initially it seemed to confirm what I found in previous comments but when I start from scratch the View that I had configured to use Search API's provided tag caching is reset to uncached and the OOM issue persists. When I change it to Search API's tag caching things actually work normally again (i.e., the exact opposite of the result I get and can still reproduce in #12).

flocondetoile’s picture

Same issue here. I've got a search api view which go into an infinite loop.
Trying #9 by swapping this block from \Drupal\metatag_views\MetatagViewsCacheWrapper::cacheGet

 if ($type === self::RESULTS) {
      $cutoff = $this->plugin->cacheExpire($type);
      // Values to set: $view->result, $view->total_rows, $view->execute_time,
      // $view->current_page and pass row tokens to metatag display extender.
      if ($cache = \Drupal::cache($this->plugin->resultsBin)->get($this->plugin->generateResultsKey())) {
        if (!$cutoff || $cache->created > $cutoff) {
          $view = $this->plugin->view;
          $view->result = $cache->data['result'];
          // Load entities for each result.
          $view->query->loadEntities($view->result);
          $view->total_rows = $cache->data['total_rows'];
          $view->setCurrentPage($cache->data['current_page'], TRUE);
          $view->execute_time = 0;
          $extenders = $view->getDisplay()->getExtenders();
          if (isset($extenders['metatag_display_extender'])) {
            $extenders['metatag_display_extender']->setFirstRowTokens($cache->data['first_row_tokens']);
          }
          return TRUE;
        }
      }
      return FALSE;
    }

Edit : The views has the same issue. It run normally only if I disabled the cache on the views (currently configured with the search API tag).

zcht’s picture

@wells yes, disabled the submodule, set the search api view to cache: none. so everything works. the metatags i need for the views were realized via hooks (even if that's not so nice).

if i use the patch from the linked issue (#3255547), the problem seems to be solved. both when the cache tags are enabled and disabled. the submodule seems to work correctly then.

GuillaumeG’s picture

Same issue here after updating from 8.x-1.16 to 8.x-1.18 with Search API and SolR.
Reverting back 1.16 fixes the issue.

I realised my memory leak issue was caused by metatag after profiling the page, here is a screenshot of the stack in case it is useful :

image of profiling out of memory issue

DamienMcKenna’s picture

That is very useful, thank you.

Is it weird to anyone else that cacheGet() is being loaded twice in the same execution process?

wells’s picture

@DamienMcKenna see #11 above -- it seems to get triggered over and over because when the cached view data is being unserialized it re-executes the view (checking the cache again in the process).

DamienMcKenna’s picture

WiseMike’s picture

I have the same problem. I use it with the Search API. The rollback of the metatag module to version 8.x-1.16 helped

Eugene Bocharov’s picture

FileSize
38.23 KB

I found that Drupal\search_api\Plugin\views\row\SearchApiRow during prerender adds entity to each result row inside keys _object and _item, and adds view to this node as a property.

$entity->view = $this->view;

And while MetatagViewsCacheWrapper saves cache on postrender, those entities objects with views inside go to the cache and obviously cause infinite loop on restoring from cache.

$plugin->prepareViewResult($view->result) in the MetatagViewsCacheWrapper::doDeferredCacheSet() only cleans up _entity key in the results, but entity still remains in _object, _item and _relashionship_objects.

I don't know the right way to solve this yet.

dvincitravis’s picture

I, too, have a view that pulls from a Solr index. I, too, am getting out-of-memory errors when trying to load a page which includes this view.

The out-of-memory errors began when I upgraded from Metatag 8.x-1.16 to 8.x-1.18.

Rolling back to 8.x-1.16 fixes the issue.

DamienMcKenna’s picture

Should we disable the cache as a temporary work-around? It's a little harsh, but it would at least stop this part of the problem.

wells’s picture

Maybe. But #21 sounds promising for getting closer to a solution here. With 8.x-1.19 just going out we may as well keep working at this a bit, no?

socketwench’s picture

I ran into this issue yesterday after updating to 1.18. Whenever anyone hit the adoption page -- a big SAPI views page -- it would go into a recursive loop, OOM, and then k8s would kill the container. Causing an outage.

You can see in the screenshot it bouncing between the session handler, memcache, and metatag repeatedly:

screenshot with backtrace

The only hint of this error was when we ran the site locally and the following log messages were written:

[07-Jan-2022 14:06:57 America/Chicago] PHP Fatal error:  Allowed memory size of 335544320 bytes exhausted (tried to allocate 20480 bytes) in /var/www/html/modules/contrib/memcache/src/Driver/MemcachedDriver.php on line 72
[07-Jan-2022 14:06:57 America/Chicago] PHP Fatal error:  Allowed memory size of 335544320 bytes exhausted (tried to allocate 65536 bytes) in /var/www/html/core/lib/Drupal/Core/Database/Query/Merge.php on line 46
[07-Jan-2022 14:08:45 America/Chicago] PHP Fatal error:  Allowed memory size of 335544320 bytes exhausted (tried to allocate 65536 bytes) in /var/www/html/core/includes/errors.inc on line 60

Rolling back to 1.16.0 fixed the issue.

DamienMcKenna’s picture

FileSize
335 bytes

The first step might be to add search_api as a test dependency?

Has anyone confirmed the smallest configuration required to trigger this problem?

dww’s picture

To make this issue easier to work with, I'm moving the huge backtrace from comment #2 into a .txt attachment...

wells’s picture

Re: #26 -- if you have Lando handy this repo is just Metatags + Search API + default database search configuration: https://github.com/CascadePublicMedia/metatag-3245876

dww’s picture

Version: 8.x-1.16 » 8.x-1.x-dev
Issue summary: View changes

p.s. Sounds like 8.x-1.6 is the last version without this bug. Moving to 1.x-dev for now since that seems more appropriate. Added rolling back to that as a temporary work-around under proposed resolution.

zcht’s picture

Thanks @dww

when i created this issue, i had 1.18 in use. under 1.18 the metatag views submodule only works with the patch, as i already confirmed in #15 (so did some other users).

in the meantime i did an update to 1.19, the patch is included. everything works very well, whether with cache tags on/off. by itself you can close this issue now, because with 1.19 in my eyes everything is fine. or are there still objections?

ps: thanks to all for analysis and solution suggestions, the drupal community is simply the best community :)

MrDaleSmith’s picture

I had this issue after updating to 1.18, and can confirm it seems to have been resolved by updating to 1.19

wells’s picture

It seems there is some confusion (#30, #31) between this issue and #3255547: Metatag Views breaks Views previews and some Views pages as the original description for this issue is actually part of #3255547: Metatag Views breaks Views previews and some Views pages. Note that what is being discussed here is out-of-memory issues in relation to Metatag v1.18+ and (at least) Search API views and cache and that is still an issue with the latest version of Metatag.

Eugene Bocharov’s picture

Configuration from https://github.com/CascadePublicMedia/metatag-3245876 works for me without errors now if metatag updated to 1.19 . But if I enable memcache module, turn on view's caching and check option "Use replacement tokens from the first row" in the Search API view metatag configuration I get "Out of memory ..." error.
I thought, although we got error after implementing new funcionallity in metatag, the root of the problem might be outside the matatag module.

MrDaleSmith’s picture

@wells I'm not confused: I had the out of memory issue on Metatag 1.18 and it's been resolved by upgrading to 1.19. I had it on a SAPI view with the cacheing disabled (as it used Facets), so it may still be an issue if the view is cached.

wells’s picture

Ah, ok. Thanks for testing, @Eugene Bocharov.

That may explain the same error but different repro steps I got with that repo despite the same circumstances. I think I was experiencing both issues on at least one of my sites but maybe only one issue on another. I will perform some new testing with the 8.x-1.19 release and try to clear this up further.

Also worth noting that multiple people here report this issue when using Memcache but at least one (#16) experiences it with Redis as well. Maybe that doesn’t amount to much but I figured it’s worth pointing out given the findings in #33.

wells’s picture

@MrDaleSmith thanks for clarifying. I think #3255547: Metatag Views breaks Views previews and some Views pages fixed more than I realized and what remains does appear to be specifically related to caching.

Eugene Bocharov’s picture

I think the issue could be resolved on the search_api side. I've created an issue and proposed the patch there https://www.drupal.org/project/search_api/issues/3258375

Renrhaf’s picture

Having the same issue with a Redis cache system in use (D9.3, Metatag 1.19)
Using patches from https://www.drupal.org/project/search_api/issues/3258375 and https://www.drupal.org/project/metatag/issues/3258346 fixed it. Thanks Eugene.

DamienMcKenna’s picture

Separate issues were posted in Facets & Metatag modules that identifies the custom cache system as causing a problem: #3258080: Facets disappear on refresh and #3261473: Views cache wrapper overrides other modules cache logic

smustgrave’s picture

Can also confirm the patch from https://www.drupal.org/project/search_api/issues/3258375 worked for us.