Cache – v šabloně automatické generace klíče? Nemožnost zjištění z presenteru?

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

Zdravím,

navazuji na následující diskuzní vlákno https://forum.nette.org/…ru-nette-2-0, jenž se již několikrát zde na fóru vyskytlo, ale k věci.

Pokud použijeme v šabloně makro {cache „klic“} ,tak se vygeneruje cache, avšak nikoliv pod klíčem „klic“ nýbrž se mu přiřadí tag „klic“, a klíč se vygeneruje automaticky (snad se nemýlím), ale díky této skutečnosti není možné z presenteru zjistit existenci cache.

V ideálním případě by návrh měl být lazy a inicializovat se až v šabloně, ale mnohdy se toto nedá zařídit, zvláště, když člověk má dokončený podstatně rozsáhlý projekt a cache přidává až v případě, když je to potřeba, podle zjištěné zátěže z praxe.

Smysl, proč tomu takto je, je předpokládám, kvůli správnému návrhu, aby presenter nečetl z šablony, ale osobně bych to jako veliký hřích neviděl – presenter má data prezentovat, tudíž by měl mít možnost, zda-li šablona potřebuje data k překreslení či nikoliv.

Co si celkově o tomto myslíte?

Navrhoval bych možnost v případě, že se zapíše onen klíč {cache „muj-klic“} bylo by možné v presenteru ověřit jeho existenci?

Děkuji za názory

Filip Procházka
Moderator | 4668
+
0
-

Rozhodně by se hodila možnost ověření existence klíče, ale to je dost komplikované, vzhledem k tomu, z čeho se ten klíč seskládáva.

David už se k tomu několikrát vyjadřoval.

Buď si uděláš metodu na načítání dat

public function getData()
{
	return $this->model->...;
}

a pak ji v šabloně voláš

{cache neco}
{foreach $prsenter->getData() as $row} ...

Nebo si do šablony předáš nějaký „lazy“ objekt, který vykoná dotaz až když je to potřeba. Což dělá například Nette\Database a NotORM automaticky. U dibi, to není tak zřejmé, ale dá se to také, pomocí fluent.

$this->template->data = $this->db->select('*')->from('tabulka');

a v šabloně

{cache neco}
{foreach $data as $row} ...
frosty22
Člen | 373
+
0
-

Jo jistě, tak pomocí volání metody z šablony by to samozřejmě udělat šlo, ale pouze to mi nepřijde přímo košér, nežli možnost zjištění cache z presenteru. A ano chápu, že je problém zjistit klíč, když se skládá takto složitě, ale spíše mě zajímá otázka, proč se tak skládá? Ano v případě, že nevytvořím klíč explicitně:

{cache}…{/cache}

Tak potom ano generace je ok, ale pokud ho uvedu:

{cache „klic“}…{/cache}

tak potom, by se ten klíč mohl takto pojmenovat, tedy aby to případně nekolidovalo, pokud je šablona includována i na další místech, tak bych možná spojil název klíče, např: „Presenter:action:klic“ .. podle toho by tedy poté byla možnost zavést metodu do presenteru, např: checkTemplateCache(„klic“) a v tuto chvili, už presenter/action víme, čili by to nemělo být problém vytáhnout.

frosty22
Člen | 373
+
0
-

Ikdyž vlastně to co píši výše je hloupost – proč vázat cache na presenter/action, v případě, že bude cache v layoutu (či includované části), tak by se to generovalo zbytečně vícekrát. Asi nejjednodušeji bych prostě, v případě, že je klíč uvedený použil ten ⇒ s tím programátor musí počítat, že namespace pro šablony je stejný, čili při použití stejných klíčů na více cache, tak budou kolidovat → více nelogické mi přijde nepoužívat onen klíč, ale jako tag, jako je to nyní.

Patrik Votoček
Člen | 2221
+
0
-

představ si že máš akci která podle parametru posílá do šablony úplně jiná data

frosty22
Člen | 373
+
0
-

V tomto případě, složím klíč cache stejně jako kdekoliv jinde, například i pokud v presenteru použiji cache, tak musím brát na toto ohled:

<?php
$key = array("mujklic", $param1, $param2);
$output = $cache->load($key);
if ($value === NULL) {
   $output = ... něco co používá param1, param2
   $cache->save($key, $output);
}
?>

A stejně tak v šabloně, např.:

{cache array("mujklic",$param1,$param2)}
  ... něco ...
{/cache}
--\

V podstatě je to sjednocené chování

Editoval frosty22 (14. 8. 2011 13:40)

Filip Procházka
Moderator | 4668
+
0
-

Nastuduj si jak teď funguje cachovani, sepiš RFC a můžeš i napsat proof-of-concept implementaci. Jo a vymysli, jak to udělat zpětně kompatibilně. A žádné

{cache array("mujklic",$param1,$param2)}

A počítá tvé řešení i s tím, že můžu šablony různě vyměňovat?

frosty22
Člen | 373
+
0
-

Já to nemyslel nikterak zle, pouze mě zajímalo, proč tomu tak je, jelikož jak jsi uváděl výše „David už se k tomu několikrát vyjadřoval“, tak mě pouze zajímal onen argument.

A jak funguje cachování teď? No vezmu-li v potaz, pouze tuto problematiku – klíče, tak cache se ukládá pod konkrétní klíč, který je její identifikátorem, klíčem může být i pole – na tomto není moc, co řešit.

U maker cache, mi to není však přímo jasné, jelikož sice zde je řádek, který generuje klíč:

<?php
public static function createCache(Nette\Caching\IStorage $cacheStorage, $key, & $parents, $args = NULL)
{
if ($args) {
  if (array_key_exists('if', $args) && !$args['if']) {
    return $parents[] = (object) NULL;
  }
  $key = array_merge(array($key), array_intersect_key($args, range(0, count($args))));
}
....
}
?>

avšak pouze v případě, že jsou předány argumenty $args, avšak zde se už možná ztrácím:

<?php
return Latte\PhpWriter::using($node)->write('<?php if (Nette\Latte\Macros\CacheMacro::createCache($netteCacheStorage, %var, $_g->caches, %node.array?)) { ?>',
?>

zde se tedy předá jako %var onen vygenerovaný klíč a jako %node.array ostatní argumenty, tagy, expirace, a zároveň zadaný „klíč“, jako „tag“.

Jinak „různě vyměňovat“ tím myslíš, že se dané makro může vyskytovat např. v layout, či v nějaké části, která se includuje – potom tedy, ano to může kolidovat, na druhou stranu, ale jak jsem psal výše, pokud klíč uvedu, tak toto musím logicky očekávat.

Alternativně pokud, máš na mysli, že se ona šablona uvnitř upraví, což jelikož klíč nebude závislý na obsahu, tak se cache nesmaže, tak to je též očekávané chování – pokud používám obecně cache, a upravím uvnitř cache výstup, také musím očekávat, že je nacacheovaný a tudíž ji invalidovat ručně (či mít na development vypnuto).

Editoval frosty22 (14. 8. 2011 16:26)