MemoryStorage nemaže záznamy podle tagů
- josef.sabl
- Člen | 153
V aplikaci mi nějak zlobí mazání cache podle tagů… Záznam se prostě nesmaže.
Je možné, že tahle funkce není doprogramovaná? https://api.nette.org/…age.php.html#79
Dle této funkce u Memcache mi přijde, že není… https://api.nette.org/…age.php.html#189
Vypadá, že umí mazat pouze „vše“.
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Ano, to je schválně. Prostě to neumí :)
Tak to je frustrace :-( Používám k obživě framework, který má prostě bugy a navíc je má schválně.
Neměla by tedy v případě, že je ta třída omezená třeba vyhodit výjimku, že to, o co se uživatel snaží není podporované? A nebo alespoň smazat vše. A ne jen tupě „neudělat nic“?
Minimálně by bylo fajn to uvést v dokumentaci.
Cituju z dokumentace:
„Kromě představeného úložiště FileStorage najdete v Nette Framework také … MemoryStorage pro ukládání do paměti s životností aktuálního požadavku.“
„Každé položce v cache můžeme přiřadit seznam tagů.“
„Společně s uložením článku do databáze zavoláme příkaz clean(), který smaže z cache položky dle tagu.“
Jak z toho chudák uživatel má poznat, že MemoryStorage prostě mazat podle tagů neumí? Chudák uživatel to pozná tak, že na něj nadřízení řvou, protože aplikace zobrazuje blbosti a tráví celý den debugováním svého kódu místo psaním kódu nového :)
Je nějaký důvod, proč to „prostě neumí“? Proč to není možné udělat podobně, jako u Memcache?
Omlouvám se, jestli to je moc flame, ale tohle je pro mě kruté probuzení
do reality.
Díky moc ;-)
Editoval josef.sabl (5. 2. 2013 17:46)
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Ano, to je schválně. Prostě to neumí :)
Nemohla by ta implementace vypadat třeba takto?
Přijde mi to celkem jednoduché. A nebo mi něco uniká? Bude to mít vliv na výkon? Paměť?
class MyMemoryStorage extends \Nette\Caching\Storages\MemoryStorage
{
private $tagMap = array();
private $keyMap = array();
public function remove($key)
{
foreach ($this->keyMap[$key] as $tag => $void)
{
unset($this->tagMap[$tag][$key]);
}
unset($this->keyMap[$key]);
parent::remove($key);
}
public function write($key, $data, array $dp)
{
if (!empty($dp[\Nette\Caching\Cache::TAGS]))
{
foreach ($dp[\Nette\Caching\Cache::TAGS] as $tag)
{
$this->tagMap[$tag][$key] = true;
$this->keyMap[$key][$tag] = true;
}
}
parent::write($key, $data, $dp);
}
public function clean(array $conds)
{
if (!empty($conds[\Nette\Caching\Cache::ALL]))
{
parent::clean($conds);
}
else if (!empty($conds[\Nette\Caching\Cache::TAGS]))
{
foreach ($conds[\Nette\Caching\Cache::TAGS] as $tagToClean)
{
if (isset($this->tagMap[$tagToClean]))
{
foreach ($this->tagMap[$tagToClean] as $keyToClean => $void)
{
$this->remove($keyToClean);
}
}
}
}
}
}
Editoval josef.sabl (5. 2. 2013 17:59)
- Filip Procházka
- Moderator | 4668
Ano, uniká ti, že to není bug. Nevidím důvod, proč by tahle třída měla umět pracovat s tagy. Pokud po tom hodně toužíš, můžeš poslat pullrequest.
Ale máš pravdu, že by měla minimálně vyhazovat výjimku, že tenhle způsob mazání neumí. Na druhou stranu, byl by to docela hnusný BC break.
Já například MemoryStorage používám pouze pro testovací prostředí v PHPUnitu. Na to abys měl pár položek v poli je to trochu moc velká režie, mít jeden array obalený celou instancí Cache, ne?
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Ano, uniká ti, že to není bug. Nevidím důvod, proč by tahle třída měla umět pracovat s tagy. Pokud po tom hodně toužíš, můžeš poslat pullrequest.
Bug je to v tom, že ta třída se chová zcela jinak, než je napsáno v dokumentaci. Bug je v tom, že existuje funkce s nějakými parametry, které něco znamenají, ale ta třída je zahodí a tváří se, jako by se nechumelilo. Pokud by vyhodila při pokusu o mazání pomocí tagů výjimku, nepovažoval bych to za bug ale jen chybějící funkcionalitu.
Rozumím např. tomu, proč má prázdnou funkci lock, protože zamykání funguje automaticky. Ale funguje.
Proč by tato třída měla umět pracovat s tagy? Protože ji jako pomocníka používá jiná třída, která s tagy pracuje (Cache). Pokud se ptáš, tak to znamená, že buďto a) jsou k ničemu tagy a nebo b) je k ničemu tato třída.
Toužím. Jinak můžu zahodit cca půlroční práci, dát výpověď a jít si hodit mašli :) Proto už jsem si to naprogramoval :)
Ne vážně, nechci to shazovat a omlouvám se za ostřejší tón v té první odpovědi. Není to tam tedy opravdu implementované z toho důvodu, že to autor nepovažoval za důležité nebo je tam nějaký háček? Je to moje řešení v pořádku nebo něco přehlížím?
Editoval josef.sabl (5. 2. 2013 18:18)
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Já například MemoryStorage používám pouze pro testovací prostředí v PHPUnitu. Na to abys měl pár položek v poli je to trochu moc velká režie, mít jeden array obalený celou instancí Cache, ne?
Nemám pár položek v poli, mám na tom postavený model, který se nejdříve podívá, jestli není věc, která ho zajímá v proměnné (MemoryStorage), pokud ne, podívá se do MemcacheStorage a pokud není ani tam, načte ji z databáze.
Ve chvíli, kdy je nějaká věc změněná, model cache podle nějaké logiky invaliduje a vynutí přenačtení z databáze. Což se mi nedělo, protože MemoryStorage informaci pořád držela :)
Editoval josef.sabl (5. 2. 2013 18:21)
- Filip Procházka
- Moderator | 4668
Pošli pullrequest a nad konkrétní implementací se můžeme bavit na githubu.
Ale myslím si, že to není implementované, protože to autor nepovažoval
za důležité. Připadá mi to dost absurdní, takhle šíleně obalovat
jednoduchý array celým Cache
za jiným účelem,
než request-lifetime cache v testech.
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Ale máš pravdu, že by měla minimálně vyhazovat výjimku, že tenhle způsob mazání neumí. Na druhou stranu, byl by to docela hnusný BC break.
No, pokud se někde někdo snaží cache invalidovat a ona to nedělá, tak je to skrytý bug a já na takovém místě bych byl rád, kdybych se o něm dověděl.
A nebylo by lepší tam tu podporu doprogramovat? Trvám na tom, že pokud tam není, tak jsou zbytečné buďto tagy a nebo tahle storage :)
- josef.sabl
- Člen | 153
Filip Procházka napsal(a):
Pošli pullrequest a nad konkrétní implementací se můžeme bavit na githubu.
Ale myslím si, že to není implementované, protože to autor nepovažoval za důležité. Připadá mi to dost absurdní, takhle šíleně obalovat jednoduchý array celým
Cache
za jiným účelem, než request-lifetime cache v testech.
To je asi ten rozdíl pohledu. Ty vidíš jednoduchý array, já vidím cache storage. A mrkni, v jakém namespace ta třída je ;-) Memcache je taky přece vlastně jen jednoduchý array. Akorát drží mezi requesty. A kolik je k tomu nabaleno věcí… celý filejournal.
- Filip Procházka
- Moderator | 4668
Filip Procházka napsal(a):
Ale máš pravdu, že by měla minimálně vyhazovat výjimku, že tenhle způsob mazání neumí.
A pullrequest bude?