ich möchte eine konkrete CMS-Seite aus dem Cache löschen bzw. von vornherein verhindern, dass diese Seite in „prod“ gecached wird.
Hintergrund ist, dass auf der Seite ein eigenes CMS-Element ist, welches Daten von einer externen API einliest. Der Abruf der Daten unterscheidet sich inhaltlich, wenn der Nutzer angemeldet ist, oder nicht. Wenn der Nutzer sich zwischenzeitlich an- oder abmeldet, wird die Seite aber immer aus dem Cache geholt, was zu falschen Inhalten führt (zumindest in „prod“).
Da ich keine Stelle kenne, wo man einstellen kann, dass eine Seite nicht gecached werden soll, verfolge ich aktuell den folgenden Ansatz:
class CacheSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
HttpCacheItemWrittenEvent::class => 'onHttpCacheItemWrittenEvent'
];
}
public function onHttpCacheItemWrittenEvent(HttpCacheItemWrittenEvent $event): void
{
if (in_array('cms-page-6649bcc2caf84a0baf1dff814326daa1', $event->getTags())) {
error_log($event->getItem()->getKey());
}
}
}
Der Subscriber triggert den Moment, nachdem die betroffene CMS-Seite in den Cache geschrieben wurde. Dadurch kann ich den entsprechenden Schlüssel ermitteln.
Aber wie kann ich nun den Eintrag aus dem Cache entfernen? Noch besser wäre natürlich direkt zu verhindern, dass die Seite in den Cache wandert. Da habe ich aber kein Ereignis gefunden.
Im Resolver wirst du keine Möglichkeit haben, den Cache zu beeinflussen (vermutet, nicht im Quelltext nachgesehen). Daher mein Verweis auf den Controller. Ich bin in dem Thema aber auch nicht wirklich drin, daher nur die geäußerte Vermutung.
Danke fürs Teilen, @Max_Shop – das klingt erschreckend vertraut.
Wir haben ein sehr ähnliches Verhalten bei dynamischen Produktgruppen festgestellt:
Im Backend werden Änderungen (z. B. am Filter) sofort korrekt übernommen – im Frontend hingegen nur nach einem vollständigen redis-cli FLUSHALL. Selbst gezielte Cache-Invalidierung per xkey-Header, Varnish-BAN-Requests oder dem Entfernen relevanter Redis-Keys bringt keine sichtbare Änderung im Frontend. Wir setzen dabei ebenfalls Redis und Varnish ein.
Du hast weiter oben den Controller \Shopware\Storefront\Controller\ProductListingController::listing erwähnt – diesen haben wir ebenfalls geprüft, konnten aber bisher keinen zuverlässigen Einstiegspunkt für eine nachhaltige Cache-Invalidierung über diesen Weg finden. Es scheint, als ob der Cache an anderer Stelle (ggf. tief in der Stream-Logik oder CMS-Resolver) hängt.
Vielleicht hilft unser Erfahrungsbericht ja weiter – oder andere Entwickler:innen erkennen ähnliche Symptome und können das Thema dort oder hier ergänzen.
Ist halt immer die Frage, wie dynamisch Dynamische Produktgruppen sein sollten. Wenn diese bei jedem Request neu berechnet werden würden, das würde sich vermutlich bei der Resourcenlast spürbar auswirken. Ist aber auch wieder nur eine Vermutung. Hatte bisher noch nie das Vergnügen mich mit dem Cache ernsthaft auseinanderzusetzen.
Ja, genau dieser Punkt beschäftigt uns auch schon eine ganze Weile. Natürlich ist uns bewusst, dass eine vollständige Neuberechnung bei jedem Request aus Performance-Sicht keine Option wäre – aber der Begriff „dynamische Produktgruppe“ suggeriert eine gewisse Reaktivität, die derzeit einfach nicht gegeben ist.
Besonders kritisch: Sobald Redis und Varnish im Einsatz sind, greifen weder die Funktion „Cache leeren“ im Admin noch die Indexierung via Konsole oder Backend. Das Frontend zeigt weiterhin veraltete Produkt-Listings an.
Es ist aktuell nicht ganz klar, ob Redis oder Varnish oder die Kombination beider Systeme diese Aktualisierung verhindert – aber das Verhalten ist eindeutig reproduzierbar. Die dynamische Produktgruppe wird erst dann korrekt angezeigt, wenn man redis-cli FLUSHALL ausführt, also den gesamten Redis leert – was in der Praxis keine nachhaltige Lösung ist.
Die eigentlichen Cache-Tags (z. B. product_stream_result_<streamId>) werden zwar gesetzt und auch über Varnish übermittelt, doch deren gezielte Invalidierung (per PURGE/BAN oder Redis-Key-Delete) zeigt keine sichtbare Wirkung im Frontend. Damit ist die Bezeichnung „dynamisch“ aus unserer Sicht irreführend.
Für uns ist das ein ziemlich schwerwiegendes Problem – denn so sind dynamische Produktgruppen in einem performanten, gecachten Setup faktisch nicht nutzbar.
Also das spezielle Problem mit den dynamischen Produktgruppen besteht schon länger. In jedem Produkt wird die ID der dynamischen Produktgruppe gespeichert. Wenn man aber die Produktgruppe ändert, dann werden die IDs nicht aktualisiert. Da muss man halt die Produkte alle neu Indexieren.
Danke für die Ergänzung – das ist ein wichtiger Punkt. Wir haben genau dieses Verhalten ausführlich untersucht, insbesondere in Kombination mit Redis und Varnish.
Die reine Reindexierung (z. B. über das Backend oder CLI) hilft in einem solchen Setup leider nicht weiter. Zwar werden die Produktdaten aktualisiert, aber:
Der Redis-Cache (product_stream_result_*, cms_page_resolver_*) wird nicht automatisch invalidiert.
Varnish erhält keinen BAN oder PURGE – die Seiten werden also weiterhin aus dem HTTP-Cache ausgeliefert.
Ergebnis: Im Backend sieht man die neuen Produkte, aber im Frontend erscheinen sie erst nach einem manuellen FLUSHALL in Redis oder einem gezielten BAN in Varnish.