Maximum execution time exceeded – NRecursiveDirectoryIteratorFixed
- kuty.cz
- Člen | 33
Ahoj,
na jednom starsim projektu pouzivam Nette vicemene jen ke kesovani, ale narazim posledni dobou stale casteji na maximum execution time exceeded. To by samo o sobe nebylo nic divnyho, protoze server ve spickach nestiha, ale v 90% konci na tride NRecursiveDirectoryIteratorFixed.
Nemel nekdo podobny problem? Predpokladam, ze se jedna o problem prave pri prochazeni kese, protoze souboru je v jednom storage asi 100tis., ale at zkousim cokoliv, nemuzu to nijak vyresit.
Pouzivam v2.0.7
Diky za kazdy tip
- kuty.cz
- Člen | 33
soubory samotne kese… mam v jedne tabulce priblizne 100tis. polozek a k tem se z ruznych zdroju (jine DB, LDAP..) datahuji dalsi informace a neco se i pocita.
Vetsinou se zobrazuje v prumeru 100 polozek, ale i presto by byl vypocet pokazde casove narocny, takze proto se to kesuje a dodatecne informace se nacitaji z kese, ktera se invaliduje po urcitym timeoutu.
- enumag
- Člen | 2118
Při takovém množství se ani moc nedivím, že to trvá tak dlouho… Řešení:
- Neinvalidovat v závislosti na čase, místo toho přidej tagy. Ty tagy mohou být např. datum.
- Vytvoř cron, který vždy invaliduje nějaké už neplatné tagy. Informace který záznam patří kterému tagu je myslím uložená v journalu takže by nemělo být potřeba procházet všechny soubory v cache jako nyní, což by mělo být mnohem rychlejší. Stejně bych to ale raději invalidoval cronem než při standardním požadavku.
- enumag
- Člen | 2118
Nette s určitou pravděpodobností maže všechny již nevalidní záznamy. A tehdy musí samozřejmě každý soubor po jednom projít (každý záznam má v sobě uvedeny závislosti). Přitom se to právě zasekne. Teď když koukám na implementaci, tak to ještě trochu upřesním:
- Je třeba zajistit aby se na daném storage nikdy nespouštěla metoda clean(). Tedy jednak ji nesmíš spouštět sám a druhak musíš výše zmíněnou pravděpodobnost nastavit na 0.
- Invalidace pomocí tagů soubory skutečně neprochází, takže když budeš invalidovat přes journal, mělo by to být ok:
// $journal získáš z DI containeru
/** @var $journal \Nette\Caching\Storages\IJournal */
$journal->clean(array(Cache::TAGS => /* pole tagů ke smazání */));
EDIT: S redisem zkušenosti nemám, dej vědět jak to dopadne pokud ho zkusíš. ;-)
Editoval enumag (10. 1. 2013 10:18)