Skip to content

Commit ba57eb1

Browse files
committed
Fix out of bounds error in the resampler
When awaiting the resamplers to finish resampling, we need to make a copy of the resamplers dict, because new resamplers could be added or removed while we are awaiting, which would cause the results to be out of sync. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 448e6fc commit ba57eb1

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414

1515
## Bug Fixes
1616

17-
<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
17+
- Fix a bug in the resampler that could end up with an *IndexError: list index out of range* exception when a new resampler was added while awaiting the existing resampler to finish resampling.

src/frequenz/sdk/timeseries/_resampling.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,13 @@ async def resample(self, *, one_shot: bool = False) -> None:
495495
self._config.resampling_period,
496496
)
497497

498+
# We need to make a copy here because we need to match the results to the
499+
# current resamplers, and since we await here, new resamplers could be added
500+
# or removed from the dict while we awaiting the resampling, which would
501+
# cause the results to be out of sync.
502+
resamplers = self._resamplers.copy()
498503
results = await asyncio.gather(
499-
*[r.resample(self._window_end) for r in self._resamplers.values()],
504+
*[r.resample(self._window_end) for r in resamplers.values()],
500505
return_exceptions=True,
501506
)
502507

@@ -508,7 +513,7 @@ async def resample(self, *, one_shot: bool = False) -> None:
508513
dict[Source, Exception | asyncio.CancelledError],
509514
{
510515
source: results[i]
511-
for i, source in enumerate(self._resamplers)
516+
for i, source in enumerate(resamplers)
512517
# CancelledError inherits from BaseException, but we don't want
513518
# to catch *all* BaseExceptions here.
514519
if isinstance(results[i], (Exception, asyncio.CancelledError))

0 commit comments

Comments
 (0)