bug #40040 [Finder] Use a lazyIterator to close files descriptors when no longer used (jderusse)
This PR was merged into the 4.4 branch.
Discussion
----------
[Finder] Use a lazyIterator to close files descriptors when no longer used
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | fix #35508
| License | MIT
| Doc PR | -
The `RecursiveDirectoryIterator` class open the file on `__construct`.
Because we Inject an instance of `RecursiveDirectoryIterator` inside the \AppendIterator` class, php opens a lot of file even before iterating on it.
This PR adds a new `LazyIterator` class that instantiate the decorated class only when something starts iterating on it.
When the iteration is over, it unset the variable to close let the decorated class clean things (ie. close the files)
Commits
-------
7117e1a798
Use a lazyintertor to close files descriptors when no longer used
This commit is contained in:
commit
dc20a31179
@ -20,6 +20,7 @@ use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\LazyIterator;
|
||||
use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\SortableIterator;
|
||||
|
||||
@ -635,7 +636,9 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
|
||||
$iterator = new \AppendIterator();
|
||||
foreach ($this->dirs as $dir) {
|
||||
$iterator->append($this->searchInDirectory($dir));
|
||||
$iterator->append(new \IteratorIterator(new LazyIterator(function () use ($dir) {
|
||||
return $this->searchInDirectory($dir);
|
||||
})));
|
||||
}
|
||||
|
||||
foreach ($this->iterators as $it) {
|
||||
|
30
src/Symfony/Component/Finder/Iterator/LazyIterator.php
Normal file
30
src/Symfony/Component/Finder/Iterator/LazyIterator.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Finder\Iterator;
|
||||
|
||||
/**
|
||||
* @author Jérémy Derussé <jeremy@derusse.com>
|
||||
*/
|
||||
class LazyIterator implements \IteratorAggregate
|
||||
{
|
||||
private $iteratorFactory;
|
||||
|
||||
public function __construct(callable $iteratorFactory)
|
||||
{
|
||||
$this->iteratorFactory = $iteratorFactory;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
yield from ($this->iteratorFactory)();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Finder\Tests\Iterator;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Finder\Iterator\LazyIterator;
|
||||
|
||||
class LazyIteratorTest extends TestCase
|
||||
{
|
||||
public function testLazy()
|
||||
{
|
||||
new LazyIterator(function () {
|
||||
$this->markTestFailed('lazyIterator should not be called');
|
||||
});
|
||||
|
||||
$this->expectNotToPerformAssertions();
|
||||
}
|
||||
|
||||
public function testDelegate()
|
||||
{
|
||||
$iterator = new LazyIterator(function () {
|
||||
return new Iterator(['foo', 'bar']);
|
||||
});
|
||||
|
||||
$this->assertCount(2, $iterator);
|
||||
}
|
||||
|
||||
public function testInnerDestructedAtTheEnd()
|
||||
{
|
||||
$count = 0;
|
||||
$iterator = new LazyIterator(function () use (&$count) {
|
||||
++$count;
|
||||
|
||||
return new Iterator(['foo', 'bar']);
|
||||
});
|
||||
|
||||
foreach ($iterator as $x) {
|
||||
}
|
||||
$this->assertSame(1, $count);
|
||||
foreach ($iterator as $x) {
|
||||
}
|
||||
$this->assertSame(2, $count);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user