Use a lazyintertor to close files descriptors when no longer used

This commit is contained in:
Jérémy Derussé 2021-01-30 17:17:32 +01:00
parent 945c7c590c
commit 7117e1a798
No known key found for this signature in database
GPG Key ID: 2083FA5758C473D2
3 changed files with 87 additions and 1 deletions

View File

@ -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) {

View 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)();
}
}

View File

@ -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);
}
}