What I’m trying to do:
Hi Anvil and friends
I’ve got an application with a WebSocket in JS that is handling some stream of data. My application then pulls that data on user demand and displays it.
I’ve noticed that every time the data is pulled, a reference to the copied object is kept internally by Skulpt, leading to a memory leak over time. This leak persists no matter if the passed object is a string (then it’s leaked in Skulpt’s str() builtin), a dict (dict() builtin), or list.
To try and circumvent this I thought of passing a dict from Python to a JS function, having it fill the data, and then using it back in Python so to avoid returning a new object from JS. This made me notice that the dictionary on the Python end doesn’t reflect changes made by JS.
I created a MRE in the clone link below. The code has a button that when pressed calls a JS script function with a Python dict. The JS function returns a random string and adds a value to the passed dictionary. The Python code then finally throws the result into a textbox. The returned string needs to be random to force a new string allocation and not let any constant-string optimizations happen under the hood. This chain of events serves to mock the on demand pulling of information from my WebSocket.
By running the cloned app and repeatedly pressing the button you can observe the following findings:
- the new key added to the dict by the JS function is absent after its return.
- monitoring the app with memory profiling (I tested with both firefox and Chrome’s developer tools) shows every press of the button causes the returned value to be leaked as it remains referenced internally by Skulpt. This memory isn’t freed, and the more you press the more the “baseline” memory consumption grows.
I tried del
ing the dict in the Python code, explicitly marking references as null
or undefined
in the JS code, and various other techniques but the root cause is that Skulpt keeps holding on to references after I’m done with them and marked them as such.
tl;dr:
- is it possible to populate a dict passed from Python to JS?
- returning a value from JS to Python leaks memory. How to handle?
Cheers!
Clone link: