Podivné chování cache – neřeší různá prostředí
- 2bfree
- Člen | 248
Mám na localhostu dvě různá prostředí pro tutéž aplikaci:
aplikace.localhost
aplikace-prod.localhost
v bootstrap.php mám tento kód
<?php
if($_SERVER['SERVER_NAME']=="aplikace-prod.localhost"){
Nette\Environment::setMode(Nette\Environment::DEVELOPMENT,FALSE);
Nette\Environment::setMode(Nette\Environment::PRODUCTION,TRUE);
Nette\Environment::setName('production');
}
?>
Pro produkční prostředí mám nastavené promazávání whitespace (strip) na generovaný HTML kód. Když promažu cache, tak každé prostředí zvlášť funguje tak jak si představuji že má. Nicméně, jakmile je jednou vygenerovaná cache pro jedno prostředí, tak i to druhé si bere vygenerovaný kód.
Snad je to trochu srozumitelné. Dotaz zní, jak to udělat, aby to fungovalo správně? Např.: Jak nastavit, aby soubor v cache měl například url prefix
- kravčo
- Člen | 721
Mohlo by pomôcť pri vytváraní cache zavolať novú metódu derive() s argumentom názvu prostredia:
<?php
use Nette\Environment;
// ...
// získanie cache...
$cache = Environment::getCache('HTML');
// rozšírenie namespace {current} -> {current}.{mode}
$cache = $cache->derive(Environment::getName());
if (isset($cache[$key])) {
echo $cache[$key];
exit;
}
// ...
- 2bfree
- Člen | 248
kravčo napsal(a):
Mohlo by pomôcť pri vytváraní cache zavolať novú metódu derive() s argumentom názvu prostredia:
<?php use Nette\Environment; // ... // získanie cache... $cache = Environment::getCache('HTML'); // rozšírenie namespace {current} -> {current}.{mode} $cache = $cache->derive(Environment::getName()); if (isset($cache[$key])) { echo $cache[$key]; exit; } // ...
Já nikde přímo cache nevolám a nikdy jsem s tím ještě nepracoval. Mohl bys mi prosím poradit, kde má být toto napsáno? V boostrapu nebo v BasePresenteru?
- Filip Procházka
- Moderator | 4668
Co takhle trochu elegantněji? :)
class Configurator extends Nette\Object
{
public static function createCacheStorage()
{
$context = new Nette\Context;
$context->addService('Nette\\Caching\\ICacheJournal', callback('Nette\Configurator::createCacheJournal'));
$environment = Nette\String::webalize(Nette\Environment::getName());
$dir = Nette\Environment::expand('%tempDir%/cache/' . $environment);
umask(0000);
@mkdir($dir, 0755, TRUE); // @ - directory may exists
return new Nette\Caching\FileStorage($dir, $context);
}
}
do configu
service.Nette-Caching-ICacheStorage.factory = Configurator::createCacheStorage
service.Nette-Caching-ICacheStorage.run = TRUE
tohle by ti mělo globálně, pro všechno v Nette, co používá
Nette\Caching\ICacheStorage
(čili prakticky všechno) nastavit
další úroveň složek pro ukládání cache, podle prostředí :)
Editoval HosipLan (29. 12. 2010 9:26)
- 2bfree
- Člen | 248
HosipLan napsal(a):
Co takhle trochu elegantněji? :)
class Configurator extends Nette\Object { public static function createCacheStorage() { $context = new Nette\Context; $context->addService('Nette\\Caching\\ICacheJournal', callback('Nette\Configurator::createCacheJournal')); $environment = Nette\String::webalize(Nette\Environment::getName()); $dir = Nette\Environment::expand('%tempDir%/cache/' . $environment); umask(0000); @mkdir($dir, 0755, TRUE); // @ - directory may exists return new Nette\Caching\FileStorage($dir, $context); } }
do configu
service.Nette-Caching-ICacheStorage.factory = Configurator::createCacheStorage service.Nette-Caching-ICacheStorage.run = TRUE
tohle by ti mělo globálně, pro všechno v Nette, co používá
Nette\Caching\ICacheStorage
(čili prakticky všechno) nastavit další úroveň složek pro ukládání cache, podle prostředí :)
Tak tohle dělá přesně to co chci, jenom doplním, že v config.ini by mělo být
<?php
service.Nette-Caching-ICacheStorage.factory = Nette\Configurator::createCacheStorage
service.Nette-Caching-ICacheStorage.run = TRUE
?>
Teď je jen otázka, či se tohle dostane do standardní verze Nette. Mě osobně by se to velice líbilo. Možná s tím, že by se to nevytvářelo do Nette\Environment::expand(‚%tempDir%/cache/‘ . $environment); ale rovnou do Nette\Environment::expand(‚%tempDir%/‘ . $environment);
Případně, kdyby se to do standardní verze Nette nedostalo, jak tohoto chování dosáhnout jinak?
- 2bfree
- Člen | 248
Tak to nefunguje jak má. ;( Upravil jsem dle toho co si psal a do složky production se dostane jen Nett.RobotLoader ale Nette.FileTemplate zůstane v cache adresáři. ;(
Za tímto účelem je ještě potřeba upravit stejným způsobem metody getCacheStorage() a createCacheJournal()
Editoval 2bfree (29. 12. 2010 13:02)
- 2bfree
- Člen | 248
Ale nebylo by to skvělé, úžasné a dokonalé Nette, aby na to již dávno nemyslelo a nemělo to vyřešené již dávno. Řešení je tak triviální a jednoduché, až se prostě stydím. ;)
config.ini
<?php
[production < common]
variable.tempDir = %appDir%/temp/production
[development < common]
variable.tempDir = %appDir%/temp/development
?>
- Filip Procházka
- Moderator | 4668
vidíš to, dokonce až takhle jednoduše :) to mě ani nenapadlo
Co se týče toho createCacheStorage()
tak jsem tam schválně
nepsal Nette\
, aby jsi si to udělal jako vlastní třídu a necpal
to do Nette.
Potom je tam samozřejmě problém s tím, že php neví, kde tu třídu hledat, protože robot loader si vytváří cache a až z ní ty třídy čte, takže je to takový začarovaný kruh :)
Ale dá se to snadno vyřešit
// ...
require APP_DIR . '/libs/MyConfigurator.php';
Nette\Environment::setConfigurator(new MyConfigurator);
Nette\Environment::loadConfig();
// ...
class MyConfigurator extends Nette\Configurator
{
public static function createCacheStorage()
{
// ...
}
}
a máš vlastní rozšířený konfigurátor, za cenu jednoho
require
:)
Jinak s tím žurnálem na tagy máš pravdu, to je taky potřeba upravit cestu
a mít vlastní továrničku na žurnál
Ale samozřejmě, lepší bude napsat si do configu prostě jinou cestu v jiném prostředí :) ultimátní řešení :)