bloomberg / memray

Memray is a memory profiler for Python
https://bloomberg.github.io/memray/
Apache License 2.0
13.17k stars 392 forks source link

using memray with flask and then TypeError: 'memray._memray.ProfileFunctionGuard' object is not callable #665

Closed hostobaz closed 1 month ago

hostobaz commented 1 month ago

Is there an existing issue for this?

Current Behavior

i using memray 1.13.4 flask 3.0.3 and also os ubunto 22.04.4 here's my code

app.py

from flask import Flask
from app.usecase import UseCase

app = Flask(__name__)

@app.route('/')
def index():
    usecase = UseCase()
    usecase.run()
    return "Home view"

usecase.py

import memray, time

GlobalVariables = []

class UseCase():
    def __init__(self) -> None:
        pass

    def run(self):
        suffix = time.time()
        file_name=f"output_{suffix}.bin"
        config = memray.FileDestination(path=file_name)
        with memray.Tracker(destination=config):
            LocalVariables = []
            nums: int = 10000
            for item in range(nums):
                GlobalVariables.append(item)
                LocalVariables.append(item)

        print(len(GlobalVariables))

i got error following below

Traceback (most recent call last):
  File "/home/dan/.local/share/virtualenvs/memray-G-TfFNj1/lib/python3.11/site-packages/flask/app.py", line 1473, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/.local/share/virtualenvs/memray-G-TfFNj1/lib/python3.11/site-packages/flask/app.py", line 882, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/.local/share/virtualenvs/memray-G-TfFNj1/lib/python3.11/site-packages/flask/app.py", line 880, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/.local/share/virtualenvs/memray-G-TfFNj1/lib/python3.11/site-packages/flask/app.py", line 865, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/Desktop/memray/app/app.py", line 9, in index
    usecase.run()
  File "/home/dan/Desktop/memray/app/usecase.py", line 13, in run
    with memray.Tracker(destination=config):
  File "src/memray/_memray.pyx", line 729, in memray._memray.Tracker.__exit__
  File "/usr/lib/python3.11/threading.py", line 58, in setprofile
    def setprofile(func):

TypeError: 'memray._memray.ProfileFunctionGuard' object is not callable

i am new memray and i don't know what happened what should i do

Expected Behavior

No response

Steps To Reproduce

  1. requirement.txt

    Flask==3.0.3
    memray==1.13.4
  2. pipenv install -r requirements.txt

  3. to create app.py and usecase.py

  4. then run flask run --reload

  5. go to route localhost:5000/

  6. got type error

Memray Version

1.13.4

Python Version

3.11

Operating System

Linux

Anything else?

No response

godlygeek commented 1 month ago

I can reproduce this, though I'm not sure what's going on yet. Note that it only happens if you use --reload, which means that whatever's happening, it's being triggered by Flask's reloader.

godlygeek commented 1 month ago

No, scratch that, I'm pretty sure that this can be reproduced even without Flask. What's happening here is actually a race condition in memray's tracker setup, I think, possibly coupled with a CPython bug, or at least edge case...

I'll figure out how we can fix that, but meanwhile, I think it would solve your problem if you instead ran:

flask run --without-threads --reload

to ensure that only one thread at a time is trying to call with memray.Tracker(...):