cache – tagy (ne)pochopení

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Filip111
Člen | 244
+
0
-

Ahoj, jak se projekt rozrůstá trochu se mi komplikuje invalidace cache. Nepoužívám tagy a chci se zeptat jak fungují. (dokumentaci jsem četl :)
Příklad:

mám vícejazyčný katalog (třeba zboží), to je dělené do kategorií a každá kategorie má definované svoje parametry, např. kategorie Notebooky má definované parametry velikost HDD, velikost displeje, typ procesoru apod.
Pokud změním kategorii, potřebuji invalidovat veškeré zboží v ní (např. nastavím kategorii disabled),
když upravím parametry této kategorie, potřebuji zase invalidovat kategorii a veškeré zboží v ní, když změním zboží invaliduji jen zboží, když změním jazyk (např. disabled) invaliduji vše pro daný jazyk (kategorie, parametry, zboží, zkrátka všechno).

Lze k tomu použít tagy, pokud ano tak takto?
cs
cs/category/$cid
cs/category/$cid/param
cs/category/$cid/goods/$gid

Když budu ukládat do cache zboží, musím mu předat všechny tyto tagy nebo stačí jen cs/category/$cid/goods/$gid a pokud invaliduji cs invalidují se všechny zanořené tagy?

(jde mi o to jestli to funguje jako stromová struktura a všechny listy předaného uzlu se invalidují nebo to jsou jen obyčejné kódy a musím otrocky všechno vyjmenovat…)

Případně máte nějaký best practice jak řešit invalidaci u podobně závislých objektů?

Díky.

Filip Procházka
Moderator | 4668
+
0
-

Tagy jsou pole stringů, žádný strom.

$cache->save($key, $value, array(
	Cache::TAGS => array(
		'category' . $categoryId,
		'zbozi' . $zboziId,
		...
	)
));

A když něco změníš, pak invaliduješ tag, kterého se změna týká (zboží, kategorie, parametr, …)

PS: trošku mě děsí, co to vytváříš? Najdi si na Google termín „premature optimization“.

Filip111
Člen | 244
+
0
-

ok, přečtu si.
Taky mě to děsí – zatím hledám jak z toho ven.
Čas od času nahlídnu do topicu na který jsem se už ptal Co ukládat a kdy invalidovat, (zatím jsem to nedokázal zprovoznit, resp. jsem se k tomu nedokopal).

Říkám si ale, že pro uvedený příklad by mi to stejně nijak nepomohlo.

Filip Procházka
Moderator | 4668
+
0
-

Já bych to cachování nijak nehrotil. Až to bude vypadat, že web jede pomalu, pak to začni řešit :)

PS: výborné téma, v podstatě všechno už bylo řečeno tam ;)

Editoval HosipLan (2. 1. 2012 16:10)

Filip111
Člen | 244
+
0
-

Nehrotim – ale dost mě to štve. Jde o to, že mám několik kategorií ve stromové struktuře, každá kategorie má nějaké parametry. Poslední kategorie ve stromu tyto parametry dědí ze všech nadřazených kategorií.

Pokud tedy chci načíst parametry poslední kategorie, musím nejdřív načíst strom nadřazených kategorií a pro každou navíc ještě parametry. (a protože jsem dělal DB návrh už dávno, není to uspořádaný strom ale musím jít rekurzí, takže se počet DB dotazů docela nastřádá)
Zkusím na to nemyslet :)

Filip Procházka
Moderator | 4668
+
0
-

Tak to je pak celkem oprávněné.

Asi bych celý strom „vytvořil“, dal si do pole IDčka všech řádků, které v něm budou (jenom ty kategorie category1, category20) a když se pak něco změní v kategorii invalidovat.

Když už tak i cachovat se má jednoduše :)

Filip111
Člen | 244
+
0
-

Upustil jsem od nějakého většího předělání cache a jen upravuji systém abych mohl cachovat vícejazyčné záznamy. Klíč cache je
nejakyKlic[$lang]

Narazil jsem ale na problém s invalidací – předpokládal jsem, že když invaliduji celé pole nejakyKlic, invalidují se všechny záznamy tohoto pole (pro všechny jazyky)…to se ale nestalo. Musím je invalidovat zase pomocí celého klíče nejakyKlic[$lang]

Takhle to má opravdu fungovat?
Čekal jsem chování jako u pole, ale funguje to podobně jako tagy, klíč je zase jen pouhopouhý string.

Díky.

Filip Procházka
Moderator | 4668
+
0
-

Nehledě na to, že jsem tvůj předpoklad ani nepochopil, nebylo by to zbytečně magické? Čím víc toho cache bude umět, tím bude pomalejší a pak tak trochu ztrácí smysl něco cachovat, že.

Filip111
Člen | 244
+
0
-

V dokumentaci se píše Do cache lze ukládat jakékoliv struktury, nemusí to být jen řetězec. A totéž platí i pro klíče.

Otázka tedy zní, když použiji jako klíč pole, chová se jako pole nebo jako řetězec? To přece neni žádná magie, když je to vypíchnutý v dokumentaci. Příklad:

$this->context->cache->save('klic[0]', $text0);
$this->context->cache->save('klic[1]', $text1);

Měl by některý z následujících příkazů invalidovat oba předchozí klíče nebo ne? (podle dokumentace jsem pochopil že ano, ale v reálu k invalidaci nedojde)

$this->context->cache->save('klic[]', null);
$this->context->cache->save('klic', null);

Editoval Filip111 (3. 1. 2012 18:08)

Filip Procházka
Moderator | 4668
+
0
-

Ale hlouposti… To je přece obyčejný string!

klíč jako pole je myšleno toto

$cache = new Nette\Caching\Cache($this->context->cacheStorage, 'Categories');
$cache->save(array('klic' => 1), $data);

To je kvůli tomu, když potřebuješ složitější klíč pro cache. Když máš například spoustu parametrů

$cache->save(array('sql' => "SELECT * FROM tabulka WHERE id = ?", 'params' => array(1)), $vysledek);

Už to chápeš?

Funguje to tak, že co dáš do $key tak prožene přes serialize a to bude výsledný klíč.

Pokud chceš ty něco invalidovat, použiješ tagy. Pokud chceš, aby se to invalidovalo samo, tak tomu nastavíš závislosti.

Editoval HosipLan (3. 1. 2012 19:07)

Filip111
Člen | 244
+
0
-

Teď už konečně začínám chápat… :)
Vůbec jsem si neuvědomil (nebo nevšimnul), že existujou závislosti – to mi snad pomůže vyřešit většinu problémů.