From 356c77b0b877ff66b28282dc148b80966dd48f81 Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Fri, 26 Jun 2026 11:37:35 -0400 Subject: [PATCH] fix: strip plugin timers when pickling Host to prevent save failure Host.plugin_timers holds asyncio TimerHandle objects (and their lambda callbacks) which are not picklable, causing the 5-minute state save to fail with "Can't pickle local object reset_plugin_timer..". Add Host.__getstate__ to reset plugin_timers to {} before pickling, mirroring Connection.__getstate__; timers are recreated on the next PLG. Co-Authored-By: Claude Opus 4.8 --- hbd/server/hbdclass.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hbd/server/hbdclass.py b/hbd/server/hbdclass.py index 7f7ea53..b5e190b 100644 --- a/hbd/server/hbdclass.py +++ b/hbd/server/hbdclass.py @@ -304,6 +304,14 @@ class Host: self.managers: list = [] # usernames with manager role self.monitors: list = [] # usernames with monitor role + def __getstate__(self): + """Prepare Host for pickling by excluding non-serializable timer objects.""" + state = self.__dict__.copy() + # asyncio TimerHandles (and their lambda callbacks) can't be pickled. + # They're recreated when the next PLG arrives after unpickling. + state['plugin_timers'] = {} + return state + def statedict(self): d = {} d["raw_name"] = self.name