Tools::enterCriticalSection() globalne v aplikaci?

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

Ahoj vsem, mam dotaz ohledne tohoto, co jsem vyhledal na foru a ted resim:

https://forum.nette.org/…itani-config:

V aplikaci, pokud něco složitě generuješ, nebo voláš nějaký šílený proces, měl bys zavolat Tools:enterCriticalSection() a pak z ní zase vylézt. Je to performance booster, čili když je některý request aplikace v „kritické sekci“ tak ostatní, které by do nějaké „kritické sekce“ taky chtěly vstoupit, musí počkat, dokud nezískají criticalSection.lock :)

Nj, ale to se mi pri generovani jedne cache v callbacku zablokuji vsechny ostatni volane callbackem? Koukam ted a pri cachovani callbacku se obecne skoci do locku jednoho a toho sameho souboru, nikoli locku pro danou cache, coz mi prijde scifi :-O

<?php
		if ($data instanceof NCallback || $data instanceof Closure) {
			NTools::enterCriticalSection();
			$data = $data->__invoke();
			NTools::leaveCriticalSection();
		}
?>
<?php
	/**
	 * Enters the critical section, other threads are locked out.
	 * @return void
	 */
	public static function enterCriticalSection()
	{
		if (self::$criticalSections) {
			throw new InvalidStateException('Critical section has been already entered.');
		}
		$handle = fopen((defined('TEMP_DIR') ? TEMP_DIR : dirname(__FILE__)) . '/criticalSection.lock', 'w');
		if (!$handle) {
			throw new InvalidStateException('Unable initialize critical section.');
		}
		flock(self::$criticalSections = $handle, LOCK_EX);
	}
?>

Pomerne se divim, ze toto s locky vubec funguje, ze se nehromadi pozadavky cekajici na lock a nasledne se nespusti $data->__invoke i u tech ostatnich ?? Pokud prohledam zdrojaky Nette na vyskyt „Critical“, najdu pouze zapis do Cache, SafeStream a Tools, kde je to implementovane. Co jsem prehlidl ?

Editoval Dr.Diesel (4. 11. 2010 14:48)

Filip Procházka
Moderator | 4668
+
0
-

Původně to bylo pro kombinaci soubor+řádek zvlášť, takže jsi těchto sekcí mohl mít více, ale nikdo si od změny na globální lock nestěžoval, takže buďto to nikdo nepoužívá, nebo nepotřebuje.

Zkus to používat a pak nám napiš jestli to hodně vadí, nebo ne :)

Dr.Diesel
Člen | 53
+
0
-

Samozrejme ze vadi :-D Ta stavajici implementace nedava smysl. Predstav si ze na uvodce mam nejake kratke generovani cache a nekde jinde slozite. Oboji chci ale generovat callbackem kvuli zajisteni unikatniho volani generovani (popisovalo se driv, ze je prave timto reseno). To slozite generovani mi zasekne uvodku, ktera ceka nez probehne to, co s ni absolutne nesouvisi. To je dost wtf :-D

Dal mi nejak furt neni jasny, jak ten lock zajisti, ze je to generovani volano pouze jednou. Co jsem ted zkousel, dojde napr. v pripade, ze generovani trva 10s a nakupi se pozadavky k postupnemu odbaveni tech pozadavku, ale nikoli k unikatnimu. Tj. uvnitr callbacku by bylo jeste potreba overit, zda cache uz neni vygenerovana a pripadne ji vratit. Pak by to fungovalo dle predstav.

To uz vubec nemluvim o scenari, ktery od cache pozaduju ja a sice aby se po dobu generovani zobrazovala ostatnim expirovana cache a cekal na novou pouze ten jeden, ktery ji generuje. Na to jsem si napsal jednoduchy wrapper ted odpoledne ;-)

Editoval Dr.Diesel (4. 11. 2010 16:32)

Filip Procházka
Moderator | 4668
+
0
-

Už jsem tě pochopil, to je ovšem nepříjemné.

Vždycky si ale můžeš udělat „ruční zpracování“, jako je například tady https://forum.nette.org/…ura-a-moduly?…, to by snad vstupovat do kritické sekce nemělo :)

David Grudl
Nette Core | 8139
+
0
-

Účel enterCriticalSection je v tom, že se operace řadí za sebe, namísto toho, aby se prováděli paralelně. Při paralelním provádění může snadno dojít k zahlcení, obzvlášť u HDD operací.

Může se samozřejmě stát, že tatáž operace se vykoná vícekrát (byť paralelně). Tomu by se asi dalo předejít úpravou callbacku, ale nejsem si jist.

David Grudl
Nette Core | 8139
+
0
-

Vyřešeno v Nette 2.0