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

Potential memory leak #73

Open
fantamiracle opened this issue Dec 23, 2021 · 4 comments
Open

Potential memory leak #73

fantamiracle opened this issue Dec 23, 2021 · 4 comments

Comments

@fantamiracle
Copy link

fantamiracle commented Dec 23, 2021

If you wait for a few minutes you can see the memory bloat.

pybar3 version: 0.9.7

from pybars import Compiler, strlist
import json
import time
compiler = Compiler()
from memory_profiler import profile

@profile
def replace_vars(mystr, variables):
    def _json(this, item):
        return strlist(json.dumps(item))
    if isinstance(mystr, str):
        try:
            template = compiler.compile(mystr)
        finally:
            pass
        return template(variables, helpers={"json": _json})
    return mystr

while True:
    replace_vars("{{json event}}", 
                 {'event': {'event': 'connectivity.state.changed', 'timestamp': 1640217025.7437212, 'connectStatusOk': False}, 'request': {'httpParams': {'body': '{{json event}}', 'headers': ['User-Agent: Engine', 'Content-Type: application/json'], 'method': 'post' }}})
    time.sleep(.1)

Any thoughts for a fix to a way to get around it?

@radove
Copy link

radove commented Mar 29, 2023

Did you guys ever find a resolution or workaround for this issue? We're experiencing something similar with v0.9.7

@suhjohn
Copy link

suhjohn commented Dec 15, 2023

Specifically it's this code

exec(compile(container.full_code, filename, 'exec', dont_inherit=True), mod.__dict__)

In _compiler.py that seems to keep its reference.

@suhjohn
Copy link

suhjohn commented Dec 15, 2023

@radove @fantamiracle This is the fix

for key in list(sys.modules.keys()):
# you might want to adjust the string in startswith
# to match the dynamic modules in your case
if key.startswith('pybars._templates.'):
print("removing module: ", key)
del sys.modules[key]

The dynamically generated module when compiling the template is not de-referenced. We were compiling a new template every request on a Django (the nature of the template is dynamic because it can be user generated in our use-case so we can't define them as globals), and this was causing the templates to continue to exist even if the variable that the dict is assigned to gets dereferenced

@suhjohn
Copy link

suhjohn commented Dec 15, 2023

As an addendum, as they state it, the compiler is not threadsafe, so you will need to use a lock when initializing the Compiler and compiling

lock = threading.Lock()

def compile_prompt_template(prompt: str, args: dict):
with lock:
try:
compiler = Compiler()
template = compiler.compile(prompt)
except:
pass

Something like the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants