Closed goldcode closed 7 years ago
Entirely possible that Windows select() can't be interrupted by Control-C. I would try using a SignalEvent (or a SignalQueue) and see if it actually works. For example::
async def waitkb():
goodbye = SignalEvent(signal.SIGINT)
await goodbye.wait()
print("Arrived!")
async def main():
await spawn(waitkb)
await sleep(30)
run(main)
Other options: Try running curio.run() in a different thread. Launch a task that does nothing but sleep on short-periodic timer so that the kernel wakes up to check Control-C on a regular interval.
does not help either. here's the output. exploring other options now.
Arrived!
Task(id=3, name='waitkb', <coroutine object waitkb at 0x000001F41A222518>, state='TERMINATED') never joined
this works...
from curio import *
import signal
async def waitkb():
while True:
await sleep(1)
print("Arrived!")
async def main():
await spawn(waitkb)
await sleep(30)
run(main)
with following output:
Arrived!
Arrived!
Arrived!
Arrived!
Traceback (most recent call last):
File "C:\Evobase2005\Main\EvoPro\PyTools\tests\sandbox.py", line 11, in <module>
run(main)
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\site-packages\curio\kernel.py", line 882, in run
return kernel.run(corofunc, *args, timeout=timeout)
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\site-packages\curio\kernel.py", line 168, in run
ret_val, ret_exc = self._runner.send((coro, timeout))
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\site-packages\curio\kernel.py", line 747, in _run_coro
events = selector_select(timeout)
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\selectors.py", line 323, in select
r, w, _ = self._select(self._readers, self._writers, [], timeout)
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\selectors.py", line 314, in _select
r, w, x = select.select(r, w, w, timeout)
KeyboardInterrupt
I may have omitted too much detail in haste. In the example with the SignalEvent:
async def waitkb():
goodbye = SignalEvent(signal.SIGINT)
await goodbye.wait()
print("Arrived!")
async def main():
await spawn(waitkb)
await sleep(30)
run(main)
when did the "Arrived!" message display? Did it show up immediately when you pressed Control-C? Or was it delayed for 30 seconds? If it showed up immediately, you could probably cancel the main task and bail out. Or, maybe even manually raise the KeyboardInterrupt exception (need to double check the Curio handling of that). For example:
async def waitkb():
goodbye = SignalEvent(signal.SIGINT)
await goodbye.wait()
print("Arrived!")
raise KeyboardInterrupt()
Or was it delayed for 30 seconds? yes. it was delayed.
We are restrained to windows systems for hardware centric applications due to tiny companies here in Germany which cannot put in much resources to dish out linux drivers. till now its worked pretty seamlessly though. I wonder how many people actively use curio in a windows environment? Perhaps all have their homegrown solution for shutting down. a point for the tutorial or examples perhaps? ok i know its marked somewhere that windows is not really supported...
So, I did a small experiment on my Windows machine here. I got this to work:
import signal
from curio import *
async def waitkb():
async with SignalQueue(signal.SIGINT) as goodbye:
await goodbye.get()
raise KeyboardInterrupt()
async def main():
await spawn(waitkb, daemon=True)
await sleep(30)
run(main)
This code died instantly the second I hit Control-C. This was on Windows 10.
can confirm the same on Windows 10. Many Thanks.
Traceback (most recent call last):
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\site-packages\curio\kernel.py", line 835, in _run_coro
trap = current._send(current.next_value)
File "c:\Users\DSARN\AppData\Local\Programs\Python\Python36\lib\site-packages\curio\task.py", line 96, in _task_runner
return await coro
File "C:\Evobase2005\Main\EvoPro\PyTools\apps\ngen.py", line 84, in waitkb
raise KeyboardInterrupt()
KeyboardInterrupt
2017-03-Task(id=49, name='waitkb', <coroutine object waitkb at 0x00000216E8925048>, state='TERMINATED') never joined
i have been avoiding this problem like the plague since weeks but i'm afraid sooner or later i have to grab the bull by the horns.
Am i safe in assuming for windows (10) systems, that the kernel cannot/does not react on keyboard interrupt Ctrl-C at await points?
As a test:
from the code above, if Ctrl-C is pressed at time.sleep, it exits immediately with the call stack below. this seems sensible.
however if Ctrl-C is pressed at curio.sleep, it remains non-responsive and then after 5 secs, keyboard interrupt is handled.
i have tried examples/echoserv.py also with similar results. Also had a look at #72, which seemed related and a unix-centric (await on signal) solution was provided.