classification
Title: asyncio should make it easy to enable cooperative SIGINT handling
Type: behavior Stage: needs patch
Components: Library (Lib) Versions: Python 3.7
process
Status: open Resolution:
Dependencies: 29988 31388 Superseder:
Assigned To: Nosy List: aeros, giampaolo.rodola, gregory.p.smith, ncoghlan, njs, ryanhiebert, vstinner, yselivanov
Priority: normal Keywords:

Created on 2017-09-07 19:37 by ncoghlan, last changed 2019-10-14 23:11 by aeros.

Messages (4)
msg301619 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-09-07 19:37
Issue 29988 covers the fact that with the default SIGINT handler installed, a poorly timed Ctrl-C can lead to context managers failing to even start running their __(a)exit__ methods, let alone complete them.

For the asynchronous case, the problem is even worse, as the *event loop* may be interrupted at arbitrary points if the default SIGINT handler is left in place.

To handle this robustly, it's desirable to make it easy to switch event-driven programs over to cooperative Ctrl-C handling by installing an asyncio SIGINT handler while the event loop is running, rather than leaving the default SIGINT handler in place.

(Note: while installing a cooperative SIGINT handler will enable more robust event-loop managed resource cleanup, it will have the downside that Ctrl-C won't be able to interrupt a coroutine that has incorrectly blocked the main thread)
msg301631 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2017-09-07 21:22
Some prior discussion on the old asyncio tracker:
    https://github.com/python/asyncio/pull/305#issuecomment-168714572
    https://github.com/python/asyncio/issues/341
msg301661 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-09-08 01:04
Issue 31388 is also potentially relevant here, as registering a signal handler for SIGINT isn't sufficient to cover all potential cases were Py_AddPendingCall gets called. In particular, the tests for issue 29988 use Py_AddPendingCall to emulate Ctrl-C, rather than relying on SIGINT actually being raised.
msg301669 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-09-08 02:28
As per Nathaniel's comments on issue 29988 and 31388, doing this robustly relies on:

1. the event loop being able to reliably guard itself and __aexit__ method implementations against interrupts (issue 31388)
2. "async with" statements ensuring that if the frame resumes after calling __aenter__, then it will also call __aexit__ (as was done for synchronous with statements in issue 29988)
History
Date User Action Args
2019-10-14 23:11:16aerossetnosy: + aeros
2019-09-07 12:32:21ryanhiebertsetnosy: + ryanhiebert
2017-09-08 02:28:12ncoghlansetdependencies: + with statements are not ensuring that __exit__ is called if __enter__ succeeds, Provide a way to defer SIGINT handling in the current thread
messages: + msg301669
2017-09-08 01:04:35ncoghlansetmessages: + msg301661
2017-09-07 21:22:41njssetmessages: + msg301631
2017-09-07 19:37:30ncoghlancreate