Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cdd89fb

Browse files
committed
merged branch jfsimon/issue-6203 (PR #7360)
This PR was merged into the 2.1 branch. Commits ------- f2ef6bc [FrameworkBundle] removed BC break cc3a40e [FrameworkBundle] changed temp kernel name in cache:clear 7d87ecd [FrameworkBundle] fixed cahe:clear command's warmup Discussion ---------- [FrameworkBundle] fixes cahe:clear command's warmup Solution taken is to replace the last char of the cache directory name to create a temporary cache directory, this way the temporary cache path has the same length than the real one. I tested this on several projects, in dev and prod environments. | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #6203 --------------------------------------------------------------------------- by jfsimon at 2013-03-13T12:32:25Z @toloco @gergelypolonkai @ghost-x47 @stewe it would be great if you could test this patch on your projects and report result! --------------------------------------------------------------------------- by toloco at 2013-03-13T12:41:47Z Im sorry but have the same... Notice: unserialize(): Error at offset 155 of 174227 bytes in /home/tolopalmer/Projects/shareandcoach/app/bootstrap.php.cache line 915 --------------------------------------------------------------------------- by jfsimon at 2013-03-13T12:45:04Z @toloco could you paste the backtrace in a gist? and maybe the concerned file? --------------------------------------------------------------------------- by stof at 2013-03-13T13:11:47Z @jfsimon You probably have the same issue with the name of the temporary kernel class --------------------------------------------------------------------------- by jfsimon at 2013-03-13T13:36:13Z @stof if you're right, it's a nightmare. It must be possible to write a parser/fixer for serialized objects, don't you think? --------------------------------------------------------------------------- by toloco at 2013-03-13T14:22:56Z Here you are the gist with the stack and the bootstrap.php.cache file https://gist.github.com/toloco/5152581 --------------------------------------------------------------------------- by mpdude at 2013-03-13T20:08:08Z @jfsimon Writing such a parser is painting yourself in the corner. Use a temp kernel class name of the same length as a quick fix. #7230 could bring a solution because we might be able to inject a different ConfigCache factory during the command that intercepts and substitutes Resources before they get written into the meta file. Not sure if that PR has a chance of being picked though. --------------------------------------------------------------------------- by toloco at 2013-03-14T08:19:58Z So guys? we are blocked with this problem, can I help you? I can provide more stacks if it's needed --------------------------------------------------------------------------- by mpdude at 2013-03-14T10:05:05Z @toloco Could you please post the /home/tolopalmer/Projects/shareandcoach/app/cache/dev/appDevUrlMatcher.php.meta file? That's the one that is broken. --------------------------------------------------------------------------- by jfsimon at 2013-03-14T10:15:20Z @mpdude you can find its content in the gist https://gist.github.com/toloco/5152581 (1st file, 6th line) --------------------------------------------------------------------------- by mpdude at 2013-03-14T10:24:55Z @toloco That file should contain a serialized set of Resources, it's not in the Gist. --------------------------------------------------------------------------- by jfsimon at 2013-03-14T10:33:12Z @mpdude it's more visible in the raw file: ttps://gist.github.com/toloco/5152581/raw/48a1a823b5c8e6ba03936a52e8dc0d0ff1888f8a/Error+ --------------------------------------------------------------------------- by jfsimon at 2013-03-14T10:33:27Z sorry: https://gist.github.com/toloco/5152581/raw/48a1a823b5c8e6ba03936a52e8dc0d0ff1888f8a/Error+ --------------------------------------------------------------------------- by toloco at 2013-03-14T10:37:09Z https://gist.github.com/toloco/5160317 here you are the appDevUrlMatcher.php and meta --------------------------------------------------------------------------- by jfsimon at 2013-03-14T10:51:46Z @toloco I applied @mpdude's solution (have a temp kernel class name of the same length than the real one). Could you test it to see if it fixes your problem? --------------------------------------------------------------------------- by mpdude at 2013-03-14T10:58:46Z @jfsimon Thanks! @toloco If Jean-François' fix does not work, please make sure that the .meta file you posted was the broken one? I was able to unserialize it without problems. --------------------------------------------------------------------------- by toloco at 2013-03-14T11:02:09Z Man!!!! you are the fucking boss it works!! --------------------------------------------------------------------------- by mpdude at 2013-03-14T11:04:30Z @jfsimon you just made someone happy. --------------------------------------------------------------------------- by jfsimon at 2013-03-14T11:12:39Z @toloco @mpdude \o/
2 parents 18cd187 + f2ef6bc commit cdd89fb

File tree

1 file changed

+65
-62
lines changed

1 file changed

+65
-62
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php

Lines changed: 65 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
*/
2626
class CacheClearCommand extends ContainerAwareCommand
2727
{
28-
protected $name;
29-
3028
/**
3129
* @see Command
3230
*/
@@ -57,31 +55,32 @@ protected function execute(InputInterface $input, OutputInterface $output)
5755
{
5856
$realCacheDir = $this->getContainer()->getParameter('kernel.cache_dir');
5957
$oldCacheDir = $realCacheDir.'_old';
58+
$filesystem = $this->getContainer()->get('filesystem');
6059

6160
if (!is_writable($realCacheDir)) {
6261
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir));
6362
}
6463

65-
$filesystem = $this->getContainer()->get('filesystem');
66-
$kernel = $this->getContainer()->get('kernel');
67-
$output->writeln(sprintf('Clearing the cache for the <info>%s</info> environment with debug <info>%s</info>', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));
68-
69-
$this->getContainer()->get('cache_clearer')->clear($realCacheDir);
70-
7164
if ($filesystem->exists($oldCacheDir)) {
7265
$filesystem->remove($oldCacheDir);
7366
}
7467

68+
$kernel = $this->getContainer()->get('kernel');
69+
$output->writeln(sprintf('Clearing the cache for the <info>%s</info> environment with debug <info>%s</info>', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));
70+
$this->getContainer()->get('cache_clearer')->clear($realCacheDir);
71+
7572
if ($input->getOption('no-warmup')) {
7673
$filesystem->rename($realCacheDir, $oldCacheDir);
7774
} else {
78-
$warmupDir = $realCacheDir.'_new';
75+
// the warmup cache dir name must have the same length than the real one
76+
// to avoid the many problems in serialized resources files
77+
$warmupDir = substr($realCacheDir, 0, -1).'_';
7978

8079
if ($filesystem->exists($warmupDir)) {
8180
$filesystem->remove($warmupDir);
8281
}
8382

84-
$this->warmup($warmupDir, !$input->getOption('no-optional-warmers'));
83+
$this->warmup($warmupDir, $realCacheDir, !$input->getOption('no-optional-warmers'));
8584

8685
$filesystem->rename($realCacheDir, $oldCacheDir);
8786
$filesystem->rename($warmupDir, $realCacheDir);
@@ -90,98 +89,102 @@ protected function execute(InputInterface $input, OutputInterface $output)
9089
$filesystem->remove($oldCacheDir);
9190
}
9291

93-
protected function warmup($warmupDir, $enableOptionalWarmers = true)
92+
/**
93+
* @param string $warmupDir
94+
* @param string $realCacheDir
95+
* @param bool $enableOptionalWarmers
96+
*/
97+
protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = true)
9498
{
9599
$this->getContainer()->get('filesystem')->remove($warmupDir);
96100

97-
$parent = $this->getContainer()->get('kernel');
98-
$class = get_class($parent);
101+
// create a temporary kernel
102+
$realKernel = $this->getContainer()->get('kernel');
103+
$realKernelClass = get_class($realKernel);
99104
$namespace = '';
100-
if (false !== $pos = strrpos($class, '\\')) {
101-
$namespace = substr($class, 0, $pos);
102-
$class = substr($class, $pos + 1);
105+
if (false !== $pos = strrpos($realKernelClass, '\\')) {
106+
$namespace = substr($realKernelClass, 0, $pos);
107+
$realKernelClass = substr($realKernelClass, $pos + 1);
103108
}
109+
$tempKernel = $this->getTempKernel($realKernel, $namespace, $realKernelClass, $warmupDir);
110+
$tempKernel->boot();
104111

105-
$kernel = $this->getTempKernel($parent, $namespace, $class, $warmupDir);
106-
$kernel->boot();
107-
108-
$warmer = $kernel->getContainer()->get('cache_warmer');
109-
112+
// warmup temporary dir
113+
$warmer = $tempKernel->getContainer()->get('cache_warmer');
110114
if ($enableOptionalWarmers) {
111115
$warmer->enableOptionalWarmers();
112116
}
113-
114117
$warmer->warmUp($warmupDir);
115118

119+
// fix references to the Kernel in .meta files
116120
foreach (Finder::create()->files()->name('*.meta')->in($warmupDir) as $file) {
117-
// fix meta references to the Kernel
118-
$content = preg_replace(
119-
'/C\:\d+\:"'.preg_quote($class.$this->getTempKernelSuffix(), '"/').'"/',
120-
sprintf('C:%s:"%s"', strlen($class), $class),
121+
file_put_contents($file, preg_replace(
122+
'/(C\:\d+\:)"'.get_class($tempKernel).'"/',
123+
sprintf('$1"%s"', $realKernelClass),
121124
file_get_contents($file)
122-
);
123-
124-
// fix meta references to cache files
125-
$realWarmupDir = substr($warmupDir, 0, -4);
126-
$content = preg_replace_callback(
127-
'/s\:\d+\:"'.preg_quote($warmupDir, '/').'([^"]+)"/',
128-
function (array $matches) use ($realWarmupDir) {
129-
$path = $realWarmupDir.$matches[1];
130-
return sprintf('s:%s:"%s"', strlen($path), $path);
131-
},
132-
$content
133-
);
125+
));
126+
}
134127

128+
// fix references to cached files with the real cache directory name
129+
foreach (Finder::create()->files()->in($warmupDir) as $file) {
130+
$content = str_replace($warmupDir, $realCacheDir, file_get_contents($file));
135131
file_put_contents($file, $content);
136132
}
137133

138-
// fix container files and classes
139-
$regex = '/'.preg_quote($this->getTempKernelSuffix(), '/').'/';
140-
foreach (Finder::create()->files()->name(get_class($kernel->getContainer()).'*')->in($warmupDir) as $file) {
141-
$content = file_get_contents($file);
142-
$content = preg_replace($regex, '', $content);
143-
144-
// fix absolute paths to the cache directory
145-
$content = preg_replace('/'.preg_quote($warmupDir, '/').'/', preg_replace('/_new$/', '', $warmupDir), $content);
146-
147-
file_put_contents(preg_replace($regex, '', $file), $content);
134+
// fix references to kernel/container related classes
135+
$search = $tempKernel->getName().ucfirst($tempKernel->getEnvironment());
136+
$replace = $realKernel->getName().ucfirst($realKernel->getEnvironment());
137+
foreach (Finder::create()->files()->name($search.'*')->in($warmupDir) as $file) {
138+
$content = str_replace($search, $replace, file_get_contents($file));
139+
file_put_contents(str_replace($search, $replace, $file), $content);
148140
unlink($file);
149141
}
150142
}
151143

152-
protected function getTempKernelSuffix()
144+
/**
145+
* @deprecated to be removed in 2.3
146+
*/
147+
protected function getTempSuffix()
153148
{
154-
if (null === $this->name) {
155-
$this->name = '__'.uniqid().'__';
156-
}
157-
158-
return $this->name;
149+
return '';
159150
}
160151

161-
protected function getTempKernel(KernelInterface $parent, $namespace, $class, $warmupDir)
152+
/**
153+
* @param KernelInterface $parent
154+
* @param string $namespace
155+
* @param string $parentClass
156+
* @param string $warmupDir
157+
*
158+
* @return KernelInterface
159+
*/
160+
protected function getTempKernel(KernelInterface $parent, $namespace, $parentClass, $warmupDir)
162161
{
163-
$suffix = $this->getTempKernelSuffix();
164162
$rootDir = $parent->getRootDir();
163+
// the temp kernel class name must have the same length than the real one
164+
// to avoid the many problems in serialized resources files
165+
$class = substr($parentClass, 0, -1).'_';
166+
// the temp kernel name must be changed too
167+
$name = substr($parent->getName(), 0, -1).'_';
165168
$code = <<<EOF
166169
<?php
167170
168171
namespace $namespace
169172
{
170-
class $class$suffix extends $class
173+
class $class extends $parentClass
171174
{
172175
public function getCacheDir()
173176
{
174177
return '$warmupDir';
175178
}
176179
177-
public function getRootDir()
180+
public function getName()
178181
{
179-
return '$rootDir';
182+
return '$name';
180183
}
181184
182-
protected function getContainerClass()
185+
public function getRootDir()
183186
{
184-
return parent::getContainerClass().'$suffix';
187+
return '$rootDir';
185188
}
186189
}
187190
}
@@ -190,7 +193,7 @@ protected function getContainerClass()
190193
file_put_contents($file = $warmupDir.'/kernel.tmp', $code);
191194
require_once $file;
192195
@unlink($file);
193-
$class = "$namespace\\$class$suffix";
196+
$class = "$namespace\\$class";
194197

195198
return new $class($parent->getEnvironment(), $parent->isDebug());
196199
}

0 commit comments

Comments
 (0)