Změna v nastavení produkčních režimů

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8215
+
0
-

Po vydání první 2.0 RC verze jsem narazil na koncepční chybu v nastavování produkčního / vývojářského režimu, která vedla k častým dotazům „zobrazuje se mi Debugger bar jen s časem a paměti“. Chybu jsem se pokusil opravit bez porušení kompatibility API, nicméně vyžaduje vysvětlení.

Stručně

Nastavení Configurator::setProductionMode() neovlivní, která sekce config.neon se načte. To ovlivníte druhým parametrem metody addConfig().

Dlouze

Pokud potřebujete na produkčním serveru aktivovat Debugger tak, abyste jste jej právě vy viděli ve vývojářském režimu (obvykle kontrolováno podle IP adresy), zjistíte, že jednoduché dělení na produkční/vývojové prostředí, kde na produkčním se Debugger nezobrazuje a na vývojovém ano, nedostačuje. Tedy jsou situace, kdy v produkčním prostředí chceme aktivovat vývojářský režim. Zdůraznil jsem slova prostředí (environment) a režim (mode), protože jsou klíčem k pochopení.

Metoda setProductionMode() skutečně přepíná jen onen režim, ve kterém aplikace běží, neurčuje však, kde (v jakém prostředí) běží. Kromě hodnot TRUE/FALSE lze předat i IP adresy, jak tomu je u Debugger::enable.

Naproti tomu prostředí, které se autodetekuje mezi názvy ‚production‘ a ‚development‘, rozhoduje o tom, která sekce se z config.neon načte. Nicméně žádná funkce setEnvironment() neexistuje, místo ní je tu druhý parameter metody addConfig(). Což vytváří obecnější mechanismus, kdy lze addConfig() volat vícekrát a pokaždé uvést jinou sekci.

Propojení s Debuggerem

Nastavení productionMode z Configuratoru je vlastně ekvivalentní s módem Debuggeru. Proto si lze nechat Debugger nastavit (a aktivovat) konfiguratorem. Jako volitelný parametr se uvede cesta k logům:

$configurator->enableDebugger(__DIR__ . '/../log');

Tohle volejte jako úplně první příkaz, aby byl Debugger aktivní co nejdříve.

hrach
Člen | 1838
+
0
-

Super, díky moc za info. Je to celkem dobrá workflow :)

Milo
Nette Core | 1283
+
0
-

Uvedu svůj příklad z praxe, kdy je potřeba udržovat rozdílné prostředí a režim. V podstatě jinými slovy to co popsal David.

Při vývoji na localhostu používá aplikace databázi na localhost. Ale po nasazení na ostrý server, používá aplikace databázi na db.muj-server.cz. Config vypadá takto:

common:
	parameters:
		database:
			driver: postgre
			host: db.muj-server.cz
			dbname: web

	php:
		date.timezone: Europe/Prague


	services:


	factories:


production < common:

development < common:
	parameters:
		database:
			host: localhost

Vše funguje podle očekávání. Pak se ale objeví v aplikaci chyba a já bych si rád aktivoval laděnku a debugbar i na ostrém serveru. Přistupuji z IP adresy 192.168.192.1. Do bootstrap.php si dopíšu setDebugMode():

$configurator = new Configurator;
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->setDebugMode(array('192.168.192.1'));

Tím se zajistí aktivování laděnky a debugbaru (tedy vývojářský režim) pro klienta s IP 192.168.192.1, ale prostředí zůstane production, aplikace se tedy stále připojuje k produkční databázi.

Oproti tomu u některých aplikacích chci, aby se mi prostředí vždy přepnulo na development jakmile aktivuji vývojářský režim. Do bootstrap.php stačí uvést:

$env = $configurator->isDebugMode() ? Configurator::DEVELOPMENT : Configurator::PRODUCTION;
$configurator->addConfig(__DIR__ . '/config/config.neon', $env);

Editoval Milo (26. 7. 2012 18:39)

_Martin_
Generous Backer | 679
+
0
-

Narazil jsem na drobný problém: konfigurátor má při vytváření aplikace jako výchozí hodnotu pro catchExceptions nastaveno %productionMode%. Ale z pohledu konfigurace se tento parametr chová jako prostředí.

// jsme ve vývojovém prostředí

$configurator->setProductionMode(TRUE); // nastavíme produkční režim
var_dump($configurator->isProductionMode()); // vypíše TRUE
var_dump($container->application->catchExceptions); // vypíše FALSE (očekáváno TRUE)

Aby se vypsala hodnota opravdu odpovídající nastavenému řežimu, museli bychom předat metodě addConfig druhý parametr s hodnotou Configurator::PRODUCTION. V tu chvíli by se ale načetla sekce pro produkční prostředí, což není žádoucí.

Elijen
Člen | 171
+
0
-

Co to udela, kdyz zavolas $configurator->createContainer() az po nastaveni $configurator->setProductionMode() ?

Editoval Elijen (15. 2. 2012 15:04)

_Martin_
Generous Backer | 679
+
0
-

Přesně toto, createContainer volám až po setProductionMode.

theo
Člen | 57
+
0
-

Díky, tenhle příklad byl velmi užitečný a celou problematiku dost osvětlil.

Poznamenal bych jen, že uvnitř Configurator::detectProductionMode se provádí srovnání s výstupem funkce php_uname(‚n‘), která překvapivě nemusí (protože nemá :) vracet IP adresu stroje, ale jeho hostname (pokud není nastaven pak teprve IP adresu – tak se to chová alespoň v Linuxu). Proto pokud detekce IP adresou nefunguje použijte místo ní hostname svého stroje.

David Grudl
Nette Core | 8215
+
0
-

Po uplynutí dvou měsíců bych řešení ještě upravil.

Jednak současné sekce v konfiguračním souboru, které jsou development a production, bych nahradil za local a (asi) production, aby bylo zřejmé, že se jedná o umístění.

Metodu setProductionMode() bych nahradil za setDevelopmentMode() případně setDebuggingMode() aby se zcela odlišili od názvů sekcí (umístění) v konfigu.

S tím by se i změnila proměnná systémového kontejneru z productionMode na developmentMode. Dává to tak větší smysl, protože obvykle se, pokud je zapnutý development mód, funkčnost přidává a předejde se tak negativním podmínkám if (!$container->parameters['productionMode']).

Myslím, že by to mělo jít udělat plně zpětně kompatibilně.

Michal Vyšinský
Člen | 608
+
0
-

+1 osobně se mi tato změna velmi líbí – rozhodně to bude dávat větší smysl

Tomáš Votruba
Moderator | 1114
+
0
-

+1, často se současnými slovy z těchto důvodů bojuji, super :)