fix: Add low-memory guard and cooldown for Discord message sending
This isn't quite the fix though just want to save my position till tomorrow and see what changes come up before and after
This commit is contained in:
parent
efea4a1384
commit
13e3a56fa6
@ -1,5 +1,7 @@
|
||||
# Minimal module-level state (only what we need)
|
||||
_CONFIG = {"discord_webhook_url": None, "discord_alert_webhook_url": None}
|
||||
# Cooldown after low-memory failures (epoch seconds)
|
||||
_NEXT_ALLOWED_SEND_TS = 0
|
||||
|
||||
def set_config(cfg: dict):
|
||||
"""Initialize module with minimal values from loaded config (call from main)."""
|
||||
@ -30,29 +32,41 @@ def send_discord_message(message, username="Auto Garden Bot", is_alert=False):
|
||||
Send Discord message with aggressive GC and low-memory guard to avoid ENOMEM.
|
||||
Returns True on success, False otherwise.
|
||||
"""
|
||||
global _NEXT_ALLOWED_SEND_TS
|
||||
resp = None
|
||||
url = _get_webhook_url(is_alert=is_alert)
|
||||
if not url:
|
||||
return False
|
||||
|
||||
# Respect cooldown if we recently saw ENOMEM
|
||||
try:
|
||||
import time # type: ignore
|
||||
now = time.time()
|
||||
if _NEXT_ALLOWED_SEND_TS and now < _NEXT_ALLOWED_SEND_TS:
|
||||
return False
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# 1) Free heap before TLS
|
||||
import gc # type: ignore
|
||||
gc.collect()
|
||||
try:
|
||||
# If MicroPython provides mem_free, skip send if heap is very low
|
||||
if hasattr(gc, "mem_free") and gc.mem_free() < 60000: # ~60KB threshold
|
||||
# TLS can be spiky and fragmented; be conservative.
|
||||
if hasattr(gc, "mem_free") and gc.mem_free() < 100000: # ~100KB threshold
|
||||
return False
|
||||
except:
|
||||
pass
|
||||
|
||||
# 2) Import urequests locally (keeps RAM free when idle)
|
||||
import urequests as requests # type: ignore
|
||||
gc.collect() # collect again after import to reduce fragmentation
|
||||
|
||||
# 3) Keep payload tiny
|
||||
url = str(url).strip().strip('\'"')
|
||||
content = _escape_json_str(str(message)[:160])
|
||||
user = _escape_json_str(str(username)[:40])
|
||||
content = _escape_json_str(str(message)[:140]) # trim further
|
||||
user = _escape_json_str(str(username)[:32])
|
||||
body_bytes = ('{"content":"%s","username":"%s"}' % (content, user)).encode("utf-8")
|
||||
|
||||
# Minimal headers to reduce allocations
|
||||
@ -65,6 +79,13 @@ def send_discord_message(message, username="Auto Garden Bot", is_alert=False):
|
||||
return bool(status and 200 <= status < 300)
|
||||
|
||||
except Exception as e:
|
||||
# On ENOMEM/MemoryError, back off for 30 seconds to avoid repeated failures
|
||||
try:
|
||||
if ("ENOMEM" in str(e)) or isinstance(e, MemoryError):
|
||||
import time # type: ignore
|
||||
_NEXT_ALLOWED_SEND_TS = time.time() + 30
|
||||
except:
|
||||
pass
|
||||
print("Discord webhook exception:", e)
|
||||
return False
|
||||
|
||||
@ -76,7 +97,7 @@ def send_discord_message(message, username="Auto Garden Bot", is_alert=False):
|
||||
pass
|
||||
# Free refs and force GC
|
||||
try:
|
||||
del resp, body_bytes
|
||||
del resp, body_bytes, requests
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
|
||||
1
main.py
1
main.py
@ -202,6 +202,7 @@ if wifi and wifi.isconnected():
|
||||
|
||||
# Send startup notification to Discord (with timeout, non-blocking)
|
||||
try:
|
||||
gc.collect() # free heap before HTTPS
|
||||
success = discord_webhook.send_discord_message(f"Pico W online at http://{ifconfig[0]} ✅")
|
||||
if success:
|
||||
print("Discord startup notification sent")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user