Open grvstick opened 8 months ago
I'm not sure this is an AsyncSSH problem.
Even though you are canceling main_task(), you have a catch-all "except Exception" in there, which I think will end up capturing the CancelledError from your task.cancel()
, and that will prevent the task from being cancelled. Instead, it will go back up and check if self.terminate
is set, but it won't be since you have that commented out.
As for the secondary error, that's because you are successfully cancelling the asyncssh.connect()
call in query_task
, and that causes it to attempt to run the "finally" block which references listener
, but listener
is only assigned in the case where the asyncssh.connect()
succeeds. You should probably move the "try" to be after listener is assigned if you want to refer to it in the "finally" block, or you should assign its initial value to be None
prior to the "try".
I haven't tested it, but if you put in an except CancelledError
in main_task
which raises the error to prevent the except Exception
from capturing it, I think it could fix the problem. Alternately, add a raise
after print_exc()
in the except Exception
block, or explicitly break out of the loop when you see a CancelledError
.
Thanks for the swift reply, here are a few comments
Even though you are canceling main_task(), you have a catch-all "except Exception" in there, which I think will end up capturing the CancelledError from your
task.cancel()
, and that will prevent the task from being cancelled. Instead, it will go back up and check ifself.terminate
is set, but it won't be since you have that commented out.
From what I know, this used to be the early behavior of Exception
class, and now asyncio.CancelledError
is categorized differently. To add up, changing the main_task
like this does not change the behavior.
async def main_task(self):
while not self.terminate.is_set():
try:
await self.query_task()
except ZeroDivisionError:
pass
except asyncio.CancelledError:
raise
except Exception:
print_exc()
finally:
await asyncio.sleep(3)
As for the secondary error, that's because you are successfully cancelling the
asyncssh.connect()
call inquery_task
, and that causes it to attempt to run the "finally" block which referenceslistener
, butlistener
is only assigned in the case where theasyncssh.connect()
succeeds. You should probably move the "try" to be after listener is assigned if you want to refer to it in the "finally" block, or you should assign its initial value to beNone
prior to the "try".
Omitting listener
initialization was my mistake in the beginning, and I fixed it in my main code that I'm using. I left it there because it could reproduce the problem. Even with the unbound local variable mistake, the task should be able to cancel when it was asked to cancel, or at least that is what I think.
Sorry - it looks like I missed your last post here. Were you able to resolve this issue?
Asyncssh 2.14.1 Linux mint 21.3 (ubuntu jammy) Python 3.12.0
The issue is reproducable using the following code
Running this code results in this traceback. Which is not odd, but it hangs there indefinitely.
When I ran the debugger, the main_task is not cancelled, and still runs the loop.