Skip to content

Commit 67dbfa1

Browse files
Add method to stop Select (#63)
Add method to stop `Select` instance and cleanup any pending task. Select stores async tasks that listen on the receivers. If select is removed without stopping the receivers tasks, then we get error: Task was destroyed but it is pending! We should stop all internal tasks before destoring Select. Destructor can't be async, so we do that with extra method `stop`. This method should be called when Select is no longer needed. Signed-off-by: ela-kotulska-frequenz <[email protected]>
2 parents 60e61bd + 5ea3735 commit 67dbfa1

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

src/frequenz/channels/util/_select.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class Select:
6363
6464
[Receiver][frequenz.channels.Receiver]s also function as `Receiver`.
6565
66+
When Select is no longer needed, then it should be stopped using
67+
`self.stop()` method. This would cleanup any internal pending async tasks.
68+
6669
Example:
6770
For example, if there are two receivers that you want to
6871
simultaneously wait on, this can be done with:
@@ -106,6 +109,13 @@ def __del__(self) -> None:
106109
for task in self._pending:
107110
task.cancel()
108111

112+
async def stop(self) -> None:
113+
"""Stop the `Select` instance and cleanup any pending tasks."""
114+
for task in self._pending:
115+
task.cancel()
116+
await asyncio.gather(*self._pending, return_exceptions=True)
117+
self._pending = set()
118+
109119
async def ready(self) -> bool:
110120
"""Wait until there is a message in any of the receivers.
111121

0 commit comments

Comments
 (0)