Closed (fixed)
Project:
Facets
Version:
2.0.x-dev
Component:
Code
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
19 May 2022 at 16:31 UTC
Updated:
6 Jun 2022 at 09:49 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
mkalkbrennerComment #3
mkalkbrennerI think save() is the Problem here.
@BAHbKA, could you explain the intention here more detailed?
At least we have to turn that off during config import. Or find a different solution which seems the better way.
Comment #4
mkalkbrennerCould we check if there's a change before saving the display?
Comment #7
bahbka commentedThis is done to add newly created facet as a dependency to the views view search api result query. I'm also running site install from existing config and don'e see this kind of issues on my side. I guess that problem lies in the Commerce Store Default argument, which is obviously will be null upon site install and causing issues.
Comment #8
bahbka commentedI agree that it doesn't make sense todo this resaving while synchronising configuration. Standard scenario should be:
- developer will create new facet locally
- developer will export both configuration views view source (updated by
::registerFacet()and will include facet configuration in cache tags) and newly created facet config.So when this two configurations will be deployed elsewhere, we don't need to recalculate views cache meta, it will be imported via
drush sync.But as this is very hard to reproduce for me, can you test site install with the attached patch?
Comment #9
mkalkbrennerUnfortunately the same exception is still triggered. So it seems that isSyncing() returns false.
Comment #10
bahbka commentedI've managed to reproduce the issue:
- install drupal/commerce
- enable commerce_store commerce_product
- add commerce store entity through the commerce admin UI
- add search api index for the commerce product entity
- add product store and title to the index
- create views view based on the index above
- add context filter for Store field and select "Store ID from the current store" as a default value for it.
- create "Store" (or any other) facet for this view display.
- export configuration
- install website from scratch.
After these steps user will receive an exception described here https://www.drupal.org/project/facets/issues/3281408#comment-14531352.
However patch https://www.drupal.org/project/facets/issues/3281408#comment-14531473 has resolved issue for me on the install.
Note that when you will navigate to the view display edit page, and will try to just resave it, you will get the same exception, with different trace though. Same will happen when you will try to add a facet for such view source and there is no commerce store.
mkalkbrenner, can it be that your install script ran
composer install/updateor something like this and override fix from#8?P.S: approach with
!$this->isSyncing()is taken from\Drupal\views\Entity\View::preSave()Comment #11
mkalkbrennerI reviewed the current approach again. It seems wrong to me that facets saves a view display.
A view could be used independently from a facet and can have its own cache settings. A facet has to work with the views result, regardless if it is a cached result or not and regardless if its display is cached.
But facets have to inject their cache meta data into the search_api query because that's what is altered by facets. And this query will influence view's caching.
Comment #12
bahbka commentedUnfortunately this is the only way to let Search API views view to know that it has additional cache dependency. This is needed only on facet insert op. We can change an approach to:
- Change implementation
Drupal\facets\Plugin\facets\facet_source\SearchApiDisplay\registerFacet()to system status message that will inform user that view has to be resaved.- wrap in try {
Drupal\facets\Plugin\facets\facet_source\SearchApiDisplay\registerFacet()} catch{ display same information as above} <code>Drupal\facets\Plugin\facets\facet_source\SearchApiDisplay\registerFacet()I took an approach from view resaving from the previous facet settings form submit implementation: views cache was programatically disabled.
facet_summary settings form does the same
Drupal\facets_summary\Form\FacetsSummarySettingsForm::submitForm()Comment #13
mkalkbrennerDid you consider to add the cache dependencies to the query?
I think the approach in facets was rather old.
Comment #14
bahbka commentedWell $view->save() op is actually adds it to the query() but not in obvious way: https://www.drupal.org/project/search_api/issues/3197050#comment-14483368 .
- Upon saving views, view will collect all cache metadata from all its plugins, including Search API cache plugin.
- Search Api cache plugin will prexecute search query
\Drupal\search_api\Plugin\views\cache\SearchApiTagCache::alterCacheMetadata()- When query is pre-executed it will be altered with
\Drupal\facets\FacetManager\DefaultFacetManager::alterQuery()that will include all necessary facet cache information.Comment #15
mkalkbrennerIf I understood Search API correctly, the cachable dependencies on queries are respected in real time. So I don't see the requirement to add the dependencies to the view itself.
But you already took a closer look. So are you of the opinion that this will not work?
Comment #16
mkalkbrennerBTW, could you take a quick look at #3281382: fine tune processor cache meta data.
Comment #17
bahbka commentedThis option will not work(or at least I can't see another way around) because of views cache mechanism:
- View will cache the results
- SAPI: Query will not be triggered
We need to inject facet as a dependency on a Views level and It seems very logical to me: facet source search plugin needs to be aware of a facet entity and take it into consideration every time it builds a query or results set.
Comment #18
mkalkbrennerUnfortunately this does not help because it is not an exception but a fatal error.
Comment #19
bahbka commentedSo let's go with a message that will be displayed to user once he/she have created new facet:
- Please update %view_name in order to make sure that facet results will be correctly cached.
As alternative:
Submit ticket to the Commerce Store module:
- on clean install, no Store has been created yet.
- create views view
- add contextual filter and select "Store ID from the current store" as a default value for it.
- Save a view.
Expected result:
- View will be created.
Actual:
- Fatal error.
Comment #20
bahbka commentedmkalkbrenner I'll do the both:
$view->save()with a notification to a user.Comment #21
mkalkbrennerThanks for your help! I was very busy today.
I started debugging the issue but had no time to finish it.
The message is a good idea.
I wonder if we should provide a button and/or drush command to "fix" or "update" views displays.
Maybe a message on the on the status report page would be helpful, too.
I still wonder if there's a way to detect if save() is required, in other words if something really changed. In this case we would be able to trigger the save.
Comment #22
bahbka commentedSave is required when views are actually caching the results and facets module can work with that specific cache type.
Here is an updated patch with this logic, resave a view only in case:
In general when developers will update facets version to 2.0.x-dev, and for some reason they have a view with enabled cache, they will have (it is standard drupal practise after module updates) to execute:
drush updb, which will resave all views with enabled cache and facets attached to itdrush cex, which will export views view config. This one will let to ignore the view in (3) when code will be deployed.Please let me know if you still want to get rid of
$this->getViewsDisplay()->save();logic and replace it with message.Comment #24
mkalkbrennerThe last patch seems to work.
Comment #25
mkalkbrenner