python / cpython

The Python programming language
https://www.python.org
Other
62.68k stars 30.06k forks source link

asyncio should make it easy to enable cooperative SIGINT handling #75568

Closed ncoghlan closed 1 month ago

ncoghlan commented 7 years ago
BPO 31387
Nosy @gpshead, @ncoghlan, @vstinner, @giampaolo, @njsmith, @1st1, @ryanhiebert, @aeros
Dependencies
  • bpo-29988: with statements are not ensuring that exit is called if enter succeeds
  • bpo-31388: Provide a way to defer SIGINT handling in the current thread
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.7', 'type-bug', 'library'] title = 'asyncio should make it easy to enable cooperative SIGINT handling' updated_at = user = 'https://github.com/ncoghlan' ``` bugs.python.org fields: ```python activity = actor = 'aeros' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'ncoghlan' dependencies = ['29988', '31388'] files = [] hgrepos = [] issue_num = 31387 keywords = [] message_count = 4.0 messages = ['301619', '301631', '301661', '301669'] nosy_count = 8.0 nosy_names = ['gregory.p.smith', 'ncoghlan', 'vstinner', 'giampaolo.rodola', 'njs', 'yselivanov', 'ryanhiebert', 'aeros'] pr_nums = [] priority = 'normal' resolution = None stage = 'needs patch' status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue31387' versions = ['Python 3.7'] ```

    ncoghlan commented 7 years ago

    bpo-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)

    njsmith commented 7 years ago

    Some prior discussion on the old asyncio tracker: https://github.com/python/asyncio/pull/305#issuecomment-168714572 https://github.com/python/asyncio/issues/341

    ncoghlan commented 7 years ago

    bpo-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 bpo-29988 use Py_AddPendingCall to emulate Ctrl-C, rather than relying on SIGINT actually being raised.

    ncoghlan commented 7 years ago

    As per Nathaniel's comments on bpo-29988 and 31388, doing this robustly relies on:

    1. the event loop being able to reliably guard itself and __aexit__ method implementations against interrupts (bpo-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 bpo-29988)
    willingc commented 3 months ago

    @ncoghlan I'm going to close this issue as stale, needing reframing for current state of asyncio, and related to an EOL version. If there is specific ongoing work that we feel would be a beneficial addition for asyncio, let's open a new issue based on the current asyncio implementation. Thanks (I'm going through the asyncio issues to make sure each one is actionable without too much cognitive load.). :sunny: