gcode_macro: Verify nothing attempts to pause in a get_status() callback

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor
2025-10-18 13:05:54 -04:00
parent ff667075cf
commit 6465921a5a
2 changed files with 39 additions and 35 deletions

View File

@@ -24,9 +24,12 @@ class GetStatusWrapper:
po = self.printer.lookup_object(sval, None) po = self.printer.lookup_object(sval, None)
if po is None or not hasattr(po, 'get_status'): if po is None or not hasattr(po, 'get_status'):
raise KeyError(val) raise KeyError(val)
reactor = self.printer.get_reactor()
if self.eventtime is None: if self.eventtime is None:
self.eventtime = self.printer.get_reactor().monotonic() self.eventtime = reactor.monotonic()
self.cache[sval] = res = copy.deepcopy(po.get_status(self.eventtime)) with reactor.assert_no_pause():
sts = po.get_status(self.eventtime)
self.cache[sval] = res = copy.deepcopy(sts)
return res return res
def __contains__(self, val): def __contains__(self, val):
try: try:

View File

@@ -491,41 +491,42 @@ class QueryStatusHelper:
self.pending_queries = [] self.pending_queries = []
msglist.extend(self.clients.values()) msglist.extend(self.clients.values())
# Generate get_status() info for each client # Generate get_status() info for each client
for cconn, subscription, send_func, template in msglist: reactor = self.printer.get_reactor()
is_query = cconn is None with reactor.assert_no_pause():
if not is_query and cconn.is_closed(): for cconn, subscription, send_func, template in msglist:
del self.clients[cconn] is_query = cconn is None
continue if not is_query and cconn.is_closed():
# Query each requested printer object del self.clients[cconn]
cquery = {} continue
for obj_name, req_items in subscription.items(): # Query each requested printer object
res = query.get(obj_name, None) cquery = {}
if res is None: for obj_name, req_items in subscription.items():
po = self.printer.lookup_object(obj_name, None) res = query.get(obj_name, None)
if po is None or not hasattr(po, 'get_status'): if res is None:
res = query[obj_name] = {} po = self.printer.lookup_object(obj_name, None)
else: if po is None or not hasattr(po, 'get_status'):
res = query[obj_name] = po.get_status(eventtime) res = query[obj_name] = {}
if req_items is None: else:
req_items = list(res.keys()) res = query[obj_name] = po.get_status(eventtime)
if req_items: if req_items is None:
subscription[obj_name] = req_items req_items = list(res.keys())
lres = last_query.get(obj_name, {}) if req_items:
cres = {} subscription[obj_name] = req_items
for ri in req_items: lres = last_query.get(obj_name, {})
rd = res.get(ri, None) cres = {}
if is_query or rd != lres.get(ri): for ri in req_items:
cres[ri] = rd rd = res.get(ri, None)
if cres or is_query: if is_query or rd != lres.get(ri):
cquery[obj_name] = cres cres[ri] = rd
# Send data if cres or is_query:
if cquery or is_query: cquery[obj_name] = cres
tmp = dict(template) # Send data
tmp['params'] = {'eventtime': eventtime, 'status': cquery} if cquery or is_query:
send_func(tmp) tmp = dict(template)
tmp['params'] = {'eventtime': eventtime, 'status': cquery}
send_func(tmp)
if not query: if not query:
# Unregister timer if there are no longer any subscriptions # Unregister timer if there are no longer any subscriptions
reactor = self.printer.get_reactor()
reactor.unregister_timer(self.query_timer) reactor.unregister_timer(self.query_timer)
self.query_timer = None self.query_timer = None
return reactor.NEVER return reactor.NEVER