mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	dashboard: move storage json update to a background task in edit save (#6280)
* dashboard: move storage json update to a background task in edit save * dashboard: move storage json update to a background task in edit save * fix typing * docs
This commit is contained in:
		| @@ -8,3 +8,5 @@ MAX_EXECUTOR_WORKERS = 48 | ||||
|  | ||||
|  | ||||
| SENTINEL = object() | ||||
|  | ||||
| DASHBOARD_COMMAND = ["esphome", "--dashboard"] | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import asyncio | ||||
| import contextlib | ||||
| import logging | ||||
| import threading | ||||
| from dataclasses import dataclass | ||||
| from functools import partial | ||||
| from typing import TYPE_CHECKING, Any, Callable | ||||
| from collections.abc import Coroutine | ||||
|  | ||||
| from ..zeroconf import DiscoveredImport | ||||
| from .dns import DNSCache | ||||
| @@ -71,6 +73,7 @@ class ESPHomeDashboard: | ||||
|         "mdns_status", | ||||
|         "settings", | ||||
|         "dns_cache", | ||||
|         "_background_tasks", | ||||
|     ) | ||||
|  | ||||
|     def __init__(self) -> None: | ||||
| @@ -85,6 +88,7 @@ class ESPHomeDashboard: | ||||
|         self.mdns_status: MDNSStatus | None = None | ||||
|         self.settings = DashboardSettings() | ||||
|         self.dns_cache = DNSCache() | ||||
|         self._background_tasks: set[asyncio.Task] = set() | ||||
|  | ||||
|     async def async_setup(self) -> None: | ||||
|         """Setup the dashboard.""" | ||||
| @@ -132,7 +136,19 @@ class ESPHomeDashboard: | ||||
|             if settings.status_use_mqtt: | ||||
|                 status_thread_mqtt.join() | ||||
|                 self.mqtt_ping_request.set() | ||||
|             for task in self._background_tasks: | ||||
|                 task.cancel() | ||||
|                 with contextlib.suppress(asyncio.CancelledError): | ||||
|                     await task | ||||
|             await asyncio.sleep(0) | ||||
|  | ||||
|     def async_create_background_task( | ||||
|         self, coro: Coroutine[Any, Any, Any] | ||||
|     ) -> asyncio.Task: | ||||
|         """Create a background task.""" | ||||
|         task = self.loop.create_task(coro) | ||||
|         task.add_done_callback(self._background_tasks.discard) | ||||
|         return task | ||||
|  | ||||
|  | ||||
| DASHBOARD = ESPHomeDashboard() | ||||
|   | ||||
| @@ -10,12 +10,14 @@ from esphome import const, util | ||||
| from esphome.storage_json import StorageJSON, ext_storage_path | ||||
|  | ||||
| from .const import ( | ||||
|     DASHBOARD_COMMAND, | ||||
|     EVENT_ENTRY_ADDED, | ||||
|     EVENT_ENTRY_REMOVED, | ||||
|     EVENT_ENTRY_STATE_CHANGED, | ||||
|     EVENT_ENTRY_UPDATED, | ||||
| ) | ||||
| from .enum import StrEnum | ||||
| from .util.subprocess import async_run_system_command | ||||
|  | ||||
| if TYPE_CHECKING: | ||||
|     from .core import ESPHomeDashboard | ||||
| @@ -235,6 +237,14 @@ class DashboardEntries: | ||||
|             ) | ||||
|         return path_to_cache_key | ||||
|  | ||||
|     def async_schedule_storage_json_update(self, filename: str) -> None: | ||||
|         """Schedule a task to update the storage JSON file.""" | ||||
|         self._dashboard.async_create_background_task( | ||||
|             async_run_system_command( | ||||
|                 [*DASHBOARD_COMMAND, "compile", "--only-generate", filename] | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class DashboardEntry: | ||||
|     """Represents a single dashboard entry. | ||||
|   | ||||
| @@ -9,11 +9,11 @@ import hashlib | ||||
| import json | ||||
| import logging | ||||
| import os | ||||
| import time | ||||
| import secrets | ||||
| import shutil | ||||
| import subprocess | ||||
| import threading | ||||
| import time | ||||
| from collections.abc import Iterable | ||||
| from pathlib import Path | ||||
| from typing import TYPE_CHECKING, Any, Callable, TypeVar | ||||
| @@ -40,6 +40,7 @@ from esphome.storage_json import StorageJSON, ext_storage_path, trash_storage_pa | ||||
| from esphome.util import get_serial_ports, shlex_quote | ||||
| from esphome.yaml_util import FastestAvailableSafeLoader | ||||
|  | ||||
| from .const import DASHBOARD_COMMAND | ||||
| from .core import DASHBOARD | ||||
| from .entries import EntryState, entry_state_to_bool | ||||
| from .util.file import write_file | ||||
| @@ -286,9 +287,6 @@ class EsphomeCommandWebSocket(tornado.websocket.WebSocketHandler): | ||||
|         raise NotImplementedError | ||||
|  | ||||
|  | ||||
| DASHBOARD_COMMAND = ["esphome", "--dashboard"] | ||||
|  | ||||
|  | ||||
| class EsphomePortCommandWebSocket(EsphomeCommandWebSocket): | ||||
|     """Base class for commands that require a port.""" | ||||
|  | ||||
| @@ -855,9 +853,7 @@ class EditRequestHandler(BaseHandler): | ||||
|         loop = asyncio.get_running_loop() | ||||
|         await loop.run_in_executor(None, self._write_file, filename, self.request.body) | ||||
|         # Ensure the StorageJSON is updated as well | ||||
|         await async_run_system_command( | ||||
|             [*DASHBOARD_COMMAND, "compile", "--only-generate", filename] | ||||
|         ) | ||||
|         DASHBOARD.entries.async_schedule_storage_json_update(filename) | ||||
|         self.set_status(200) | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user