Caching Framework: automatisch Cache leeren bei Datensatzänderung

Das Caching Framework lässt sich gut verwenden, um aufwändig generierte/abgefragte Daten zur Wiederverwendung schneller parat zu haben. Die prinzipielle Funktionsweise haben wir in „Caching Framework nutzen“ erklärt und findet sich auch in der Doku sowie in zahlreichen anderen Blogs.
Was aber oftmals fehlt: wie aktualisiert man den Cache bzw. invalidert ihn bei Veränderung der Daten?

Häufig hängt der Inhalt des Caches von Datensätzen ab. D.h. der Cache-Inhalt veraltet, wenn sich ein Datensatz verändert. Und damit ist auch der Ansatzpunkt für die Invalidierung klar: der processDatamap_afterDatabaseOperations-Hook im DataHandler. Er wird immer nach Datenbankoperationen („new“ bzw. „update“) aufgerufen und bekommt auch den Taballennamen mit übergeben. Somit ist es recht einfach, die eigenen Datensätze zu erkennen und auf die Veränderung zu reagieren:

EXT:my_extension/Classes/Hooks/DataHandler.php:

<?php
namespace Netzhaut\MyExtension\Hooks;

use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class DataHandler
{
    public function processDatamap_afterDatabaseOperations($status, $tableName, $recordId, array $databaseData, \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler)
    {
        if ($tableName === 'tx_myextension_domain_model_example') {
            $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('myCache');
            $cache->flushByTag('tag_123');
        }
    }
}

Dann noch am Hook registrieren, und fertig:

EXT:my_extension/ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['myextension_clearcfcache'] = 'Netzhaut\\MyExtension\\Hooks\\DataHandler';

Links

Reports – Remaining updates

Im Reports-Modul stieß ich letzens auf eine Meldung, die mich verwunderte:

„This installation is not configured for the TYPO3 version it is running.“

 

2016-02-04 15-28-09

Die TYPO3-Instanz war jedoch eine frisch aufgesetzte Installation…

Bei weitergehender Analyse, wie das Modul hierauf kommt, fand sich rasch die Ursache: die Datenbankstruktur stimmte nicht mit den Erwartungen/der hinterlegten Definitionen überein. Im Installtool unter Important actions findet sich der Database analyzer, der nähere Infos liefert.

Dubletten-Ansicht für Website-Benutzer

Wenn in größeren (aber auch generell) fe_users-Tabellen eines TYPO3 Dubletten vorhanden sind (was eigentlich nicht passieren dürfte*), kommt das Indexmanagement des mysql sehr schnell an seine Lastgrenzen.
Wenn dann gejointe Abfragen gestartet werden, gibt es einen erheblichen Performance-Unterschied wenn auch nur eine einzige Dublette im username vorhanden ist.
 
Um diese schnell finden zu können, kann man sich einfach die unten folgenden VIEWS in seine Datenbank packen (einfach im SQL-Feld des phpmyadmin abfeuern) und hat sofort eine wunderbare Übersicht über Dubletten.
Da VIEWS nur Ansichten sind, brauchen sie „keinen“ Speicherplatz und fressen auch sonst kein Brot 😉

  • Die VIEW „fe_users_dupes_witherrors_list“ stellt alle Dubletten dar, welche sogar aus Sicht von TYPO3 selbst fehlerhaft sind.
  • Die VIEW „fe_users_dupes_list“ stellt alle Dubletten dar, welche aus Sicht von TYPO3 fehlerhaft sind, aber zusätzlich auch alle die bei oben genannten Abfragen die Performance signifikant in den Keller ziehen.

Wenn man also ein sauberes TYPO3 haben möchte, welches noch dazu in der Performance keine künstlichen Bremsen im mysql haben soll, sollte also dafür sorgen das diese VIEWS immer 0 Datensätze als ergebnis liefern!

CREATE OR REPLACE VIEW `fe_users_dupes` AS
SELECT COUNT(`uid`) AS `Zeilen`,`username`,`pid`
FROM `fe_users`
GROUP BY `username`,`pid`
HAVING COUNT(`uid`)>1
ORDER BY `Zeilen` DESC
;


CREATE OR REPLACE VIEW `fe_users_dupes_list` AS
SELECT
`fe_users_dupes`.`Zeilen`,
`fe_users`.*
FROM `fe_users_dupes`
LEFT JOIN `fe_users`
ON `fe_users_dupes`.`username`=`fe_users`.`username`
;


CREATE OR REPLACE VIEW `fe_users_dupes_witherrors` AS
SELECT COUNT(`uid`) AS `Zeilen`,`username`
FROM `fe_users`
GROUP BY `username`,`pid`,`disable`,`deleted`
HAVING COUNT(`uid`)>1
ORDER BY `Zeilen` DESC
;


CREATE OR REPLACE VIEW `fe_users_dupes_witherrors_list` AS
SELECT
`fe_users_dupes_witherrors`.`Zeilen`,
`fe_users`.*
FROM `fe_users_dupes_witherrors`
LEFT JOIN `fe_users`
ON `fe_users_dupes_witherrors`.`username`=`fe_users`.`username`
;

* Das darf schon vorkommen. FE-User sind nur innerhalb ihrer Seite eindeutig (=> uniqueInPid: „Requires the field to be unique for the current PID (among other records on the same page). (Evaluated on the server only).“). Sofern FE-User aber am TCA/TYPO3 vorbei angelegt werden (z.B. Import-Routinen), greift diese Evaluierung nicht (weil eben nicht direkt in der Datenbank die Bedingung festgenagelt ist, sondern „nur“ im TCA).  

Grundkonfiguration von TYPO3 (Stand 2015)

Welche Konfiguration im Install-Tool TYPO3 geschmeidig auf unseren Servern laufen lässt, soll hier kurz erklärt werden. Die Default-Settings passen inzwischen sehr gut zu unserer Infrastruktur und unseren Erfahrungen, sodass kaum mehr Dinge zu verändern sind.

Weiterlesen»

Optimierte .htaccess für TYPO3

Über passende Regeln in der .htaccess-Datei wird die Website noch schöner, schneller und besser. Vor fast 5 Jahren hatten wir bereits im Beitrag Optimierte .htaccess fuer TYPO3 auf Apache2 von Stephan eine alternative .htaccess-Datei veröffentlicht. Die damals von TYPO3 mitgelieferte Version behandelte nur wenige Grundeinstellungen und war für den Produktivbetrieb eher suboptimal. Über die Jahre hat sich vieles getan und holte die Default-htaccess von TYPO3 auf. Ein Punkt von damals gilt aber auch noch heute

  • eine .htaccess wird mit jedem File-Hit geparst, besser wäre es natürlich die Einstellung direkt in der Apache Konfiguration der VirtualHosts vorzunehmen. Das scheitert aber vermutlich meist an entsprechenden Rechten.
  • Dadurch dass es geparst werden muss, sollte man die Datei klein halten, d.h. alle Kommentare entfernen.

Weiterlesen»