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

wait_for(coro, timeout=0) memleak #81223

Closed
ixje mannequin opened this issue May 25, 2019 · 9 comments
Closed

wait_for(coro, timeout=0) memleak #81223

ixje mannequin opened this issue May 25, 2019 · 9 comments
Labels
3.7 (EOL) end of life performance Performance or resource usage topic-asyncio

Comments

@ixje
Copy link
Mannequin

ixje mannequin commented May 25, 2019

BPO 37042
Nosy @asvetlov, @1st1, @ixje
Files
  • test_leak_minimal.py: minimal example that bleeds memory
  • test_leak_minimal_mem_consumption.png
  • 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 2019-05-25.12:09:54.889>
    labels = ['expert-asyncio', '3.7', 'performance']
    title = 'wait_for(coro, timeout=0) memleak'
    updated_at = <Date 2019-05-25.12:34:53.128>
    user = 'https://github.com/ixje'

    bugs.python.org fields:

    activity = <Date 2019-05-25.12:34:53.128>
    actor = 'ixje'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['asyncio']
    creation = <Date 2019-05-25.12:09:54.889>
    creator = 'ixje'
    dependencies = []
    files = ['48356', '48357']
    hgrepos = []
    issue_num = 37042
    keywords = []
    message_count = 6.0
    messages = ['343470', '343472', '343473', '343475', '343476', '343477']
    nosy_count = 3.0
    nosy_names = ['asvetlov', 'yselivanov', 'ixje']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'resource usage'
    url = 'https://bugs.python.org/issue37042'
    versions = ['Python 3.7']

    @ixje
    Copy link
    Mannequin Author

    ixje mannequin commented May 25, 2019

    I have a networked process that looks somewhat like this in its most basic form

    import asyncio
    
    shutting_down = False
    
    async def read_message(reader, timeout=30):
        async def _read(reader: asyncio.StreamReader):
            try:
                d = await reader.readexactly(24)
                # do something with the data
                print("I'm never called")
            except:
                return None
    
        try:
            return await asyncio.wait_for(_read(reader), timeout)
        except Exception:
            return None
    
    
    async def my_service():
        reader, writer = await asyncio.open_connection('127.0.0.1', 20333)
        while not shutting_down:
            m = await read_message(reader, timeout=0)
            if m is None:
                continue
            # else process message
    
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.create_task(my_service())
        loop.run_forever()
    

    read_message() has a default timeout of 30, but I thought setting it to 0 (instead of None) would be equal to blocking. This bleeds 16GB of memory in ~3 minutes. A minimal example is provided.

    I manually applied the patch of https://bugs.python.org/issue36613 to a self compiled build of 3.7.3 (ef4ec6e) on Ubuntu 18.04 and that did not solve the problem.

    @ixje ixje mannequin added 3.7 (EOL) end of life topic-asyncio performance Performance or resource usage labels May 25, 2019
    @asvetlov
    Copy link
    Contributor

    Thanks for the report.
    If the problem is in asyncio.wait_for() function the real network code can be stripped for the leakage example and replaced with await asyncio.sleep().

    Would you try to boil down the snippet by converting it into a code that I can execute on my laptop to reproduce the problem?

    @ixje
    Copy link
    Mannequin Author

    ixje mannequin commented May 25, 2019

    Hi Andrew,
    There is an attached minimal example (that differs from the code given in the first comment). I couldn't attach 2 files. So I pasted the code of one file to showcase how we could run into the issue, then a minimal reproducible example without network code in the attachment.

    @asvetlov
    Copy link
    Contributor

    Nice, thanks!

    @ixje
    Copy link
    Mannequin Author

    ixje mannequin commented May 25, 2019

    This is the consumption I'm seeing.

    @ixje
    Copy link
    Mannequin Author

    ixje mannequin commented May 25, 2019

    Perhaps also worth mentioning is that when we supply None as timeout value in the wait_for() in the minimal sample, then it still reports 60MB memory usage. Seems pretty steep for doing basically nothing but looping around.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @kumaraditya303
    Copy link
    Contributor

    I am unable to reproduce the leak on main branch. I profiled with memray and the rss usage is constant.

    newplot

    @iritkatriel
    Copy link
    Member

    @kumaraditya303 were you able to reproduce it with 3.7?

    @iritkatriel
    Copy link
    Member

    I tried myself - indeed I can reproduce it on 3.7 but no on main (on a MAC).

    @iritkatriel iritkatriel closed this as not planned Won't fix, can't repro, duplicate, stale Aug 26, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life performance Performance or resource usage topic-asyncio
    Projects
    Status: Done
    Development

    No branches or pull requests

    3 participants