Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignoring KeyboardInterrupt #295

Closed
amackillop opened this issue Oct 27, 2019 · 4 comments
Closed

Ignoring KeyboardInterrupt #295

amackillop opened this issue Oct 27, 2019 · 4 comments

Comments

@amackillop
Copy link

  • uvloop version: 0.14.0rc1
  • Python version: 3.7.4
  • Platform: Manjaro
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: Yes
  • Does uvloop behave differently from vanilla asyncio? How?: Vanilla loop respects the KeyboardInterrupt while uvloop ignore it.

Here is a code snippet:

import asyncio
from aiohttp import web
import uvloop

async def start(app: web.Application, host: str, port: int) -> web.AppRunner:
    """Start the server"""
    runner = web.AppRunner(app)
    await runner.setup()
    server = web.TCPSite(runner, host, port)
    await server.start()
    return runner

def main() -> None:
    """Entrypoint"""
    host = "0.0.0.0"
    port = 8000
    app = web.Application()
    loop = asyncio.get_event_loop()
    runner = loop.run_until_complete(start(app, host, port))
    print(f"======== Running on http://{host}:8000 ========\n" "(Press CTRL+C to quit)")
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        loop.run_until_complete(runner.cleanup())


if __name__ == "__main__":
    uvloop.install()
    main()

Execute the file:
python issue.py

Hit Ctrl+C.

The keyboard interrupt will be ignored. If you comment out line 28 uvloop.install() the interrupt is respected. This used to work fine, only noticed that it stopped working today.

@1st1 1st1 added the bug label Oct 28, 2019
@1st1
Copy link
Member

1st1 commented Oct 28, 2019

Seems that the regression was introduced in 48d376d cc @vladima

@1st1
Copy link
Member

1st1 commented Oct 28, 2019

Alright, I think I know what causes the bug. Will need to refactor our signals setup/processing code a bit to untangle it. I'll release RC2 tomorrow or the day after with the fix.

1st1 added a commit that referenced this issue Oct 28, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
1st1 added a commit that referenced this issue Oct 28, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
1st1 added a commit that referenced this issue Oct 28, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
1st1 added a commit that referenced this issue Oct 29, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
1st1 added a commit that referenced this issue Oct 29, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
1st1 added a commit that referenced this issue Oct 29, 2019
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD.  That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.

asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.

This translates to a slightly different behavior between asyncio &
uvloop:

1. uvloop needs to always call signal.set_wakeup_fd() when run in the
  main thread;

2. asyncio only needs to call signal.set_wakeup_fd() when a user
  registers a signal handler.

(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs.  This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs.  It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.

Issue #295.
@1st1
Copy link
Member

1st1 commented Oct 29, 2019

Fixed in uvloop 0.14.0rc2. Thank you!

@1st1 1st1 closed this as completed Oct 29, 2019
@amackillop
Copy link
Author

@1st1 I appreciate the quick turnaround. Keep up the great work.

This was referenced Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants