e3a30d882f61 draft — Alain Leufroy 1 year, 3 months ago
🚸 cpuload: kill tasks on when changing focused changeset.


It seems that asyncio does not kill subprocesses handled by a
cancelled task.
3 files changed, 20 insertions(+), 3 deletions(-)

M lairucrem/commands.py
M lairucrem/controler.py
M lairucrem/process.py
M lairucrem/commands.py +2 -0
@@ 108,6 108,8 @@ class selection:
         return self._tasks[name]
 
     async def fetch(self, node):
+        for task in self._tasks.values():
+            task.cancel()
         self._tasks = {
             name: asyncio.tasks.Task(coroutine(self, node))
             for name, coroutine in self.selectors.items()

          
M lairucrem/controler.py +1 -1
@@ 83,7 83,7 @@ class _hgwalker(ensurable, waitable, urw
                 yield line
         except asyncio.CancelledError:
             # raised when the task is interrupted
-            pass
+            await self.hgproc.kill()
 
     def _get_widget(self, line):
         content = self._parse_line(line)

          
M lairucrem/process.py +17 -2
@@ 84,7 84,8 @@ class hg:
         return self.proc
 
     async def __aiter__(self) -> AsyncIterable:
-        await self.start()
+        if not self.proc:
+            await self.start()
         val = await self._read_stdout_line()
         while val:
             yield val.decode('utf-8', 'replace')

          
@@ 110,6 111,15 @@ class hg:
 
         self.proc = None
 
+    async def kill(self):
+        if not self.proc:
+            return  # proc was not started
+        try:
+            self.proc.kill()
+            await self.stop()
+        except ProcessLookupError:
+            pass  # process already finished.
+
     def isrunning(self):
         return self.proc and self.proc.pid is not None
 

          
@@ 180,4 190,9 @@ async def hg_plain(*cmd):
     """Execute an Hg command in plain mode and return overall results."""
     env = os.environ.copy()
     env['HGPLAIN'] = '1'
-    return ''.join([line async for line in hg(*cmd, env=env)])
+    hgproc = hg(*cmd, env=env)
+    try:
+        return ''.join([line async for line in hgproc])
+    except asyncio.CancelledError:
+        await hgproc.kill()
+    return ''