Cached: cachovací aspekt pro Kdyby\Aop

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

Cached je aspekt pro Kdyby\Aop, který se postará o cachování návratových hodnot ve vaších servisách.

Použití je následující:

class MyService {

	/**
	 * @Cached\Cached
	 */
	public function getNumber() {
		return rand(1, 1000);
	}

}

Po prvním zavolání metody se návratová hodnota uloží do cache a při dalším volání se bez vykonání původní metody vrátí nacacheovaná hodnota.

Pozn.: kvůli malému bugu v Kdyby\Aop nelze v současné době importovat anotaci s pomocí use statementu (proto to ošklivé @Cached\Cached).

Instalace

Rozšíření potřebuje nainstalované Kdyby\Aop.

Nainstalujte Cached pomocí composeru:

composer require redhead/cached:@dev

A zaregistrujte extension. V Nette 2.1 takto:

extensions:
	cached: Cached\CachedExtension

Nakonec je nutné zaregistrovat samotný aspekt (pracuje se na tom, aby toto nebylo nutné):

aspects:
	- Cached\CachingAspect

A můžete začít cacheovat!

Možnosti nastavení

Samozřejmostí je i možnost nastavovat cachovaní – namespace, klíče a možnosti cachování z Nette\Caching\Cache. Způsoby nastavení jsou možné:

  1. přímo v anotaci
/**
 * @Cached\Cached(expire="1 hour", sliding=true, key="myKey", tags=["tag1"])
 */
  1. v profilu v konfiguraci
cached:
	profiles:
		myProfile:
			sliding: true
			expire: 1 hour
			tags: [tag1]

a specifikováním jména profilu v anotaci:

/**
 * @Cached\Cached(profile="myProfile")
 */

nebo pokud se neuvede anotační property profile, použije se profil jménem default. Nastavení z profilu lze přebít/doplnit anotačními propertami.


Další možnosti najdete v dokumentaci.

Enjoy a posílejte nápady, kritiku, pull requesty, atd! :)

Editoval redhead (17. 9. 2013 21:30)

Filip Procházka
Moderator | 4668
+
0
-

Skvělé! :) Zkoušel jsi měřit zpomalení? Používáš téměř nejpomalejší pointcut (anotace bez typu), tak by mě zajímalo jestli je to hodně poznat :)

redhead
Člen | 1313
+
0
-

Asi by to chtělo :) tak až bude čas..

Co znamená anotace bez typu? Vím, že anotace budou asi pomalé, ale měl jsem za to, že jen při weavingu při kompilaci a pak už se jen instanciuje CG obálka nad tou servicou. Ale asi mi něco uniká, já se do hloubky moc nevrtal.

Filip Procházka
Moderator | 4668
+
0
-

Kdyby/AOP funguje tak, že si najde aspekty (to je fofr, protože jsou otagované nebo v jeho sekci), potom si zparsuje pointcuty a vytvoří pravidla pomocí kterých prohledává servisy. Když použiješ v pointucu typ (třídu, interface, ..), tak dokáže předem vyfiltrovat služby a pravidla pak aplikuje jen na jejich subset (někdy deset, ale většinou třeba jen jedna) – tedy je to násobně rychlejší. Když použiješ pouze annotaci, musím vždy prohledat úplně všechny služby a úplně všechny jejich metody. Asi by se to dalo drobátko zoptimalizovat, ale už to moc nepůjde, protože jinak to prostě prohledat nejde :)

Každopádně tohle zpomalení je pouze a jenom v compile-time.

redhead
Člen | 1313
+
0
-

Tak princip jsem pochopil správně. Při kompilaci je jasný, že to bude pomalejší – změřit by se to dalo, ale to bych musel mít nějaký větší projekt a ten nemám. A při kompilaci mě to zas tak moc netrápí (ale asi by mohlo, kdybych měl velkej projekt :) )

Hlavní je, že to není (moc) pomalé při běhu a i tam by se dala udělat nějaká optimalizace. Zatím největší bottleneck u mě je parsování té jedné anotace, abych z ní dostal ty property – což by se dobře řešilo tím getterem na JoinPointu ;)