Commit 1fb9d17
committed
bug symfony#60260 [Serializer] Prevent
This PR was merged into the 6.4 branch.
Discussion
----------
[Serializer] Prevent `Cannot traverse an already closed generator` error by materializing Traversable input
| Q | A
| ------------- | ---
| Branch? | 6.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Issues | Fix symfony#60141
| License | MIT
### ✅ Pull Request description:
This PR addresses the issue reported in the linked ticket, specifically the error:
`Cannot traverse an already closed generator`
The fix involves converting `Traversable` input into an array using `iterator_to_array($data)`, in order to allow multiple traversals of generator-based inputs.
At first glance, it might seem that this approach significantly increases memory usage, since all generator values are stored in memory. However, this is not the case. In the current logic, the following [loop](https://github.com/symfony/symfony/blob/6.4/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php#L82-L86) already forces all values from the generator into memory:
```php
foreach ($data as &$value) {
$flattened = [];
$this->flatten($value, $flattened, $keySeparator, '', $escapeFormulas);
$value = $flattened;
}
```
Therefore, materializing the generator with `iterator_to_array() `does not increase peak memory usage in any meaningful way.
As an example, here's the comparison of peak memory usage (measured with [memory_get_peak_usage](https://www.php.net/manual/en/function.memory-get-peak-usage.php)) when processing an array of 1 million integers:
* **With the fix**: 90,044,272 bytes
* **Without the fix**: 89,936,680 bytes
The difference is negligible, confirming that the fix does not introduce a meaningful performance cost in terms of memory.
Commits
-------
c7206a9 Fix: prevent "Cannot traverse an already closed generator" error by materializing Traversable inputCannot traverse an already closed generator error by materializing Traversable input (santysisi)File tree
2 files changed
+28
-0
lines changed- src/Symfony/Component/Serializer
- Encoder
- Tests/Encoder
2 files changed
+28
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
68 | 72 | | |
69 | 73 | | |
70 | 74 | | |
| |||
Lines changed: 24 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
710 | 710 | | |
711 | 711 | | |
712 | 712 | | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
713 | 737 | | |
0 commit comments