Skip to content

asyncio loop.add_signal_handler() may not behave as expected #83946

Closed as not planned

Description

@rogerdahl
mannequin
BPO 39765
Nosy @asvetlov, @1st1, @rogerdahl
PRs
  • bpo-39765: Document caveats for asyncio add_signal_handler() #18664
  • 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:

    assignee = None
    closed_at = None
    created_at = <Date 2020-02-26.20:46:52.392>
    labels = ['type-bug', '3.8', 'expert-asyncio']
    title = 'asyncio loop.add_signal_handler() may not behave as expected'
    updated_at = <Date 2020-07-05.08:32:00.516>
    user = 'https://github.com/rogerdahl'

    bugs.python.org fields:

    activity = <Date 2020-07-05.08:32:00.516>
    actor = 'tiposchi'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['asyncio']
    creation = <Date 2020-02-26.20:46:52.392>
    creator = 'rogerdahl'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 39765
    keywords = ['patch']
    message_count = 6.0
    messages = ['362734', '362747', '362748', '362750', '362830', '373018']
    nosy_count = 4.0
    nosy_names = ['asvetlov', 'yselivanov', 'tiposchi', 'rogerdahl']
    pr_nums = ['18664']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue39765'
    versions = ['Python 3.8']

    Activity

    1. rogerdahl commented on Feb 26, 2020

      rogerdahlmannequin
      MannequinAuthor

      This is a ticket to document two ways in which the behavior of loop.set_signal_handler() may not match what the user expects.

      First, callbacks to handlers registered with loop.set_signal_handler() may be significantly delayed. I have a program where I've encountered delays of up to maybe a minute or so between hitting Ctrl-C and getting the callback for the SIGINT handler. During this time, the program works through queued aiohttp tasks. Though it's possible to have delays in callbacks for events set with signal.signal(), I haven't personally seen that, and I think that's the case for most users. So I think this point should be included in the docs.

      Second, set_signal_handler() silently and implicitly removes corresponding handlers set with signal.signal(). Though perhaps logical, this potentially removes a "fast" handler and replaces it with a "slow" one. I think this should be documented as well.

    2. asvetlov commented on Feb 26, 2020

      @asvetlov
      Contributor

      I'm sorry. but loop.set_signal_handler() method doesn't exist.

    3. asvetlov commented on Feb 26, 2020

      @asvetlov
      Contributor

      Assuming you mean loop.add_signal_handler() method, I would say that a minute-long delay is a sign of long blocking calls in your program.

      Typical asyncio program blocks the loop for 1-10 milliseconds at most, and signal handlers are called with this delay.
      This is not your case as I see.

    4. changed the title [-]asyncio loop.set_signal_handler() may not behave as expected[/-] [+]asyncio loop.add_signal_handler() may not behave as expected[/+] on Feb 26, 2020
    5. changed the title [-]asyncio loop.set_signal_handler() may not behave as expected[/-] [+]asyncio loop.add_signal_handler() may not behave as expected[/+] on Feb 26, 2020
    6. rogerdahl commented on Feb 26, 2020

      rogerdahlmannequin
      MannequinAuthor

      I'm sorry. but loop.set_signal_handler() method doesn't exist.

      Oops, fixed.

      Assuming you mean loop.add_signal_handler() method, I would say that a minute-long delay is a sign of long blocking calls in your program.

      During the delay for the callback to occur, I see my program logging work performed on other asyncio tasks and receiving timer events from another thread. So, not long blocking?

    7. asvetlov commented on Feb 27, 2020

      @asvetlov
      Contributor

      Other threads are not related.

      Speaking about the main thread that runs an event loop with the signal handler installed -- the handler is executed along with other async code.
      If the loop executes some user-provides async task -- it executes the signal handler as well if needed.

      This is why I suspect that the discussed program is not completely correct.

    8. tiposchi commented on Jul 5, 2020

      tiposchimannequin
      Mannequin

      This looks related to: https://bugs.python.org/issue32443

    9. transferred this issue fromon Apr 10, 2022
    10. kumaraditya303 commented on Oct 9, 2022

      @kumaraditya303
      Contributor

      When signal handlers are called is not guarantied, the only guarantee is that it will be called if the signal is received. It is an implementation detail e.g. if C code handles pending calls and checks for signal etc. I am -1 on adding anything regarding these implementation details, user code should not rely on any of this. This issue is most likely a bug in your code rather than in asyncio.

    11. added
      pendingThe issue will be closed if no feedback is provided
      and removed on Oct 9, 2022
    12. gvanrossum commented on Oct 9, 2022

      @gvanrossum
      Member

      @rogerdahl Have you analyzed your program more? If you can show a small demo that exhibits this behavior we'd be happy to have a look.

    13. rogerdahl commented on Oct 21, 2022

      @rogerdahl
      Author

      @gvanrossum Please leave this open for a bit and I'll try to find some time to see what the current status is.

    14. arhadthedev commented on Mar 4, 2023

      @arhadthedev
      Member

      Please leave this open for a bit and I'll try to find some time to see what the current status is.

      @rogerdahl ping?

    15. rogerdahl commented on Mar 10, 2023

      @rogerdahl
      Author

      @arhadthedev Thank you for following up. I've done some tests now and I'm unable to reproduce this. Please go ahead and close the ticket. I'll reopen it with code to reproduce if I encounter the issue again.

      Just speculating, I think the problem might have been an interplay between signal handlers in my program and in aiohttp, which I was using heavily.

      In my test, I set up an asyncio web server with delays in it to simulate slow responses, and an aiohttp based client that registered a signal handler and then hit the server with 1000 concurrent requests. The signal handler was still invoked instantly.

      aiohttp registers its own signal handlers, including for SIGINT, which I also registered for. There's a comment in the signal handler setup in aiohttp that mentions workarounds for issues with Gunicorn, so maybe they were doing something odd there.

    16. moved this from Todo to Done in asyncioon Mar 11, 2023
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      pendingThe issue will be closed if no feedback is providedtopic-asynciotype-bugAn unexpected behavior, bug, or error

      Projects

      • Status
        Done

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions