mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 22:35:08 +00:00
fix(web): a refused on-demand start leaves no request in the mailbox
POST /api/v3/display/on-demand/start delivered the request (control socket, else the file mailbox) before it checked the display service. With the service stopped the socket is absent, so the request went to the mailbox; the route then answered 400 "Display service is not running" when start_service was off, or 500 "Failed to start display service" when the start failed. The display reads that mailbox with max_age=3600 and never checks a request's timestamp, so the next time it was started it ran the refused request, pinned if asked. The service is now checked before anything is delivered, and nothing is posted when start_service is off and the service is down. When the start itself fails, the request is withdrawn from the mailbox, but only while the mailbox still holds this request_id (the compare-before-delete the display's _consume_on_demand_request uses), so a newer request posted in the meantime is left for the display. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,26 @@ def _deliver_on_demand(payload):
|
||||
return 'mailbox', reason
|
||||
|
||||
|
||||
def _withdraw_on_demand(request_id):
|
||||
"""Take a start request the route has refused back out of the mailbox.
|
||||
|
||||
The display reads the mailbox for an hour without looking at a
|
||||
request's age, so one left there after an error answer ran whenever the
|
||||
display next started. Only this request is removed: the mailbox is
|
||||
re-read and cleared only while it still holds this request_id, as the
|
||||
display's _consume_on_demand_request does, so a newer request posted in
|
||||
the meantime stays for the display to take.
|
||||
"""
|
||||
cache = _cache_manager()
|
||||
try:
|
||||
current = cache.get('display_on_demand_request', max_age=3600, memory_ttl=0)
|
||||
if isinstance(current, dict) and current.get('request_id') == request_id:
|
||||
cache.delete('display_on_demand_request')
|
||||
except Exception: # the route is answering an error already
|
||||
logger.warning("Could not withdraw on-demand request %s from the mailbox",
|
||||
request_id, exc_info=True)
|
||||
|
||||
|
||||
@api_v3.route('/display/current', methods=['GET'])
|
||||
def get_display_current():
|
||||
"""The latest display preview, as the /stream/display SSE stream sends it.
|
||||
@@ -242,6 +262,18 @@ def start_on_demand_display():
|
||||
resolved_plugin,
|
||||
)
|
||||
|
||||
# Checked before anything is delivered: a request posted and then
|
||||
# refused here stayed in the mailbox and ran when the display was next
|
||||
# started, long after the caller was told it had failed.
|
||||
service_status = _get_display_service_status()
|
||||
|
||||
if not service_status.get('active') and not start_service:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Display service is not running. Please start the display service or enable "Start Service" option.',
|
||||
'service_status': service_status
|
||||
}), 400
|
||||
|
||||
# Deliver the request over the control socket, or post it to the
|
||||
# mailbox the display process polls (DisplayController.
|
||||
# _poll_on_demand_requests). Done before any service start: a stopped
|
||||
@@ -259,15 +291,6 @@ def start_on_demand_display():
|
||||
}
|
||||
transport, socket_error = _deliver_on_demand(request_payload)
|
||||
|
||||
service_status = _get_display_service_status()
|
||||
|
||||
if not service_status.get('active') and not start_service:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Display service is not running. Please start the display service or enable "Start Service" option.',
|
||||
'service_status': service_status
|
||||
}), 400
|
||||
|
||||
# start_service means "start it if it is not running", as the UI's
|
||||
# checkbox says; _ensure_display_service_running leaves a running service
|
||||
# alone. This used to stop a running service, sleep 1.5s and start it
|
||||
@@ -285,6 +308,8 @@ def start_on_demand_display():
|
||||
service_result = _ensure_display_service_running()
|
||||
# Check if service actually started
|
||||
if service_result and not service_result.get('active'):
|
||||
if transport == 'mailbox':
|
||||
_withdraw_on_demand(request_id)
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Failed to start display service. Please check service logs or start it manually.',
|
||||
|
||||
Reference in New Issue
Block a user