-
Notifications
You must be signed in to change notification settings - Fork 51
Occasional MemoryError during Adafruit IO loop() #101
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
Comments
for the avoidance of doubt, this error also occurs with the default |
thats odd, how could you get a request for a negative amount? but yeah, a reproducable example would help a ton! |
Attached is my minimal example, it seems to be related to:
which means I receive a MQTT message every second. NB, |
A bit more digging... Not sure what line 844 achieves (some sort of decoding?) But in the error case, I have topic_len[0] = 48, and topic_len[1] = 49 Finally... after line 848: I have a negative sz of -12285, which leads to the error. I don't understand the mechanics enough to know why this has gone wrong or how to fix. |
If you are trying to reproduce... the error usually occurs every few minutes, but I have seen it go for ~6 hours with no errors |
I ran a test overnight, subscribed to 8 random feeds, but NOT to time I didn't see the MemoryError. Not exactly conclusive, but my guess is the issue is with the AIO server sending the time messages. |
Well, I've got stuck into this now... Here is some output with a print() in the _sock_exact_recv() function Normal message:
Error Case:
|
OK, this time I'm printing the number of bytes actually requested with It's now looking like I'm missing the first b'0', which throws off the sequence for everything else. Normal Message:
Error Case:
|
New idea, I'm encountering some sort of race condition by hitting the loop() function every 100ms, which happens to be the same timeout as Trying with 200ms instead... |
well, just had the error again with 200ms timeouts. Although it took a while (1 hour maybe)
|
Possibly not very helpful... but I've just had the same error while running |
Instead of using the IO library ( |
OK, I could still see the error with just MiniMQTT. Code attached.
|
Its looking like calling (The timeout=0.1 part doesn't seem to matter other than potentially limiting the overall rate due to blocking) |
@calcut Thank you for doing performance analysis, this is good info! Do you still get a MemoryError by running |
Realised I wasn't clear about that. I'm running another test with
|
I've now seen the MemoryError on both of my boards with mqtt_client.loop(timeout=0.3). code My neopixel usually gets to MAGENTA but I've never seen it go YELLOW. |
Just ran this again with the latest version of the MQTT library (5.5.0). No change (as expected). I'll have one more stab at figuring out what is happening |
partly for my own sanity, this is what I think is happening in more detail when things work as expected: We expect the response to be In this example we expect 0x18 (i.e 24) more bytes, including the topic we then request 2 more bytes to find out the topic length from there we can figure out that there are still (24 - 12 - 2 ) = 10 more bytes to come, and read those in to get the posix time. All good. When it breaks So I think the server has tried to respond with Looking at Timeouts Comparing to my previous debug efforts Fix Attempt |
Still testing... but an alternative solution may be to use non-blocking mode i.e. loop(timeout=0)
Anyway, this is currently broken because it can produce an EAGAIN exception (saying there is no data to receive) It looks like we could catch and ignore that exception in a similar way, like
I'll do a PR next week if all is looking well |
@calcut wondering if you could have a look at adafruit/circuitpython#6988 |
Not sure if I should open another issue or not. It felt like this should go here but it feels like the issue goes deeper than this: Using loop() in 8.0.0-beta always resulted in a fatal error as error.errno returned -116 which is not caught by ETIMEDOUT or EAGAIN:
My short term solution was to abs(error.errno) but like I said, it feels like this goes deeper than this library. |
This seems like it might be a circuitpython core bug. |
@framework-circuitpython Please try 8.0.0-beta.2 or later. There was an |
I've tested a modified version of the code posted above by Calcut on Looks to be resolved by adafruit/circuitpython#6988 and #133 REPL Log:
Code:
Closing this out as it seems to be resolved. |
Adafruit CircuitPython 7.1.1 on 2022-01-14; Adafruit Feather ESP32S2 with ESP32S2
Circup freeze:
Found device at /Volumes/CIRCUITPY, running CircuitPython 7.1.1.
adafruit_datetime==1.1.6
adafruit_htu31d==1.1.3
adafruit_requests==1.10.6
adafruit_ticks==1.0.1
neopixel==6.2.4
adafruit_bus_device==5.1.4
adafruit_io==5.6.1
adafruit_logging==3.7.5
adafruit_minimqtt==5.2.1
adafruit_register==1.9.8
I'm running
io.loop(timeout=0.1)
in mcy.py, line 304Normally this works fine, but every few minutes I get the above exception.
If I ignore the exception, the code continues to run with no obvious issues, but I wanted to report it anyway.
digging into adafruit_minimqtt.py, and adding a
print(bufsize)
shows me that the error on line 906 occurs when bufsize is less than zero. e.g. -13313. So I can see how the code ended up trying to allocate ~4GB of memory (2^32-13313)I also notice that the bufsize immediately before the negative one is large and positive e.g. 13365
I could try harder to make a minimum reproducable example if needed.
The text was updated successfully, but these errors were encountered: