Open controversial opened 3 years ago
Interesting, stop_session
tries to close the session nicely via the WebDriver API, which fails.
It seems that ^C
is kinda special: KeyboardInterrupt
is somehow "applied" both to await asyncio.sleep(...)
and the outer asyncio.run()
.
My guess is that asyncio.run()
receives the KeyboardInterrupt
and then it cancels its tasks, which includes the "main" task, which is at that point in sleep()
is really an anonymous future with a delayed callback. Which explains why the await asyncio.sleep()
appears to raise CanceledError
and not KeyboardInterrupt
.
This, I think, is better discussed at async-sig@python.org
Here's what it takes to get this work:
1️⃣ patch arsenic/__init__.py
like so:
async def stop_session(session: Session):
try:
await session.close()
except BaseException:
pass
await session.driver.close()
2️⃣ update the MCVE like this:
import arsenic
from arsenic.browsers import Chrome
from arsenic.services import Chromedriver
import os
import asyncio
async def main():
service = Chromedriver(log_file=os.devnull)
browser = Chrome()
driver = await arsenic.start_session(service, browser)
try:
while True:
await driver.get("https://example.com")
await asyncio.sleep(2)
except BaseException:
try:
await arsenic.stop_session(driver)
except BaseException:
pass
try:
asyncio.run(main())
except BaseException:
print("exited gracefully")
I guess the canonical advice would be along the lines of https://docs.python.org/3/library/asyncio-eventloop.html#set-signal-handlers-for-sigint-and-sigterm
Some patches are still needed though 🙈
What's the proper way to clean up and close a browser session after the event loop is interrupted?
The following program loads example.com using Arsenic every two seconds forever. However, when the user interrupts the program with a KeyboardInterrupt, the browser session can't successfully be closed.
Stopping this program yields the following error:
and then prints a warning
I can't use the
get_session
context manager because of the API design of my program. How can I make sure I clean up and close the browser session when the event loop is cancelled?