MemoryStorage nemaže záznamy podle tagů

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

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“.

Filip Procházka
Moderator | 4668
+
0
-

Ano, to je schválně. Prostě to neumí :)

josef.sabl
Člen | 153
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.

paranoiq
Člen | 390
+
0
-

bez ohledu na zamýšlený účel je to bug. má házet NotImplementedException

Filip Procházka
Moderator | 4668
+
0
-

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?