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

- David Grudl
- Nette Core | 8285
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.

- Milo
- Nette Core | 1283
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
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í.

- theo
- Člen | 58
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 | 8285
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
+1 osobně se mi tato změna velmi líbí – rozhodně to bude dávat větší smysl