Move thread safety check in issue_registry sooner (#116899)
This commit is contained in:
parent
2a4686e1b7
commit
5d5f311898
2 changed files with 76 additions and 5 deletions
|
@ -132,7 +132,7 @@ class IssueRegistry(BaseRegistry):
|
|||
translation_placeholders: dict[str, str] | None = None,
|
||||
) -> IssueEntry:
|
||||
"""Get issue. Create if it doesn't exist."""
|
||||
|
||||
self.hass.verify_event_loop_thread("async_get_or_create")
|
||||
if (issue := self.async_get_issue(domain, issue_id)) is None:
|
||||
issue = IssueEntry(
|
||||
active=True,
|
||||
|
@ -152,7 +152,7 @@ class IssueRegistry(BaseRegistry):
|
|||
)
|
||||
self.issues[(domain, issue_id)] = issue
|
||||
self.async_schedule_save()
|
||||
self.hass.bus.async_fire(
|
||||
self.hass.bus.async_fire_internal(
|
||||
EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED,
|
||||
{"action": "create", "domain": domain, "issue_id": issue_id},
|
||||
)
|
||||
|
@ -174,7 +174,7 @@ class IssueRegistry(BaseRegistry):
|
|||
if replacement != issue:
|
||||
issue = self.issues[(domain, issue_id)] = replacement
|
||||
self.async_schedule_save()
|
||||
self.hass.bus.async_fire(
|
||||
self.hass.bus.async_fire_internal(
|
||||
EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED,
|
||||
{"action": "update", "domain": domain, "issue_id": issue_id},
|
||||
)
|
||||
|
@ -184,11 +184,12 @@ class IssueRegistry(BaseRegistry):
|
|||
@callback
|
||||
def async_delete(self, domain: str, issue_id: str) -> None:
|
||||
"""Delete issue."""
|
||||
self.hass.verify_event_loop_thread("async_delete")
|
||||
if self.issues.pop((domain, issue_id), None) is None:
|
||||
return
|
||||
|
||||
self.async_schedule_save()
|
||||
self.hass.bus.async_fire(
|
||||
self.hass.bus.async_fire_internal(
|
||||
EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED,
|
||||
{"action": "remove", "domain": domain, "issue_id": issue_id},
|
||||
)
|
||||
|
@ -196,6 +197,7 @@ class IssueRegistry(BaseRegistry):
|
|||
@callback
|
||||
def async_ignore(self, domain: str, issue_id: str, ignore: bool) -> IssueEntry:
|
||||
"""Ignore issue."""
|
||||
self.hass.verify_event_loop_thread("async_ignore")
|
||||
old = self.issues[(domain, issue_id)]
|
||||
dismissed_version = ha_version if ignore else None
|
||||
if old.dismissed_version == dismissed_version:
|
||||
|
@ -207,7 +209,7 @@ class IssueRegistry(BaseRegistry):
|
|||
)
|
||||
|
||||
self.async_schedule_save()
|
||||
self.hass.bus.async_fire(
|
||||
self.hass.bus.async_fire_internal(
|
||||
EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED,
|
||||
{"action": "update", "domain": domain, "issue_id": issue_id},
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Test the repairs websocket API."""
|
||||
|
||||
from functools import partial
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
@ -358,3 +359,71 @@ async def test_migration_1_1(hass: HomeAssistant, hass_storage: dict[str, Any])
|
|||
|
||||
registry: ir.IssueRegistry = hass.data[ir.DATA_REGISTRY]
|
||||
assert len(registry.issues) == 2
|
||||
|
||||
|
||||
async def test_get_or_create_thread_safety(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test call async_get_or_create_from a thread."""
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match="Detected code that calls async_get_or_create from a thread. Please report this issue.",
|
||||
):
|
||||
await hass.async_add_executor_job(
|
||||
partial(
|
||||
ir.async_create_issue,
|
||||
hass,
|
||||
"any",
|
||||
"any",
|
||||
is_fixable=True,
|
||||
severity="error",
|
||||
translation_key="any",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def test_async_delete_issue_thread_safety(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test call async_delete_issue from a thread."""
|
||||
ir.async_create_issue(
|
||||
hass,
|
||||
"any",
|
||||
"any",
|
||||
is_fixable=True,
|
||||
severity="error",
|
||||
translation_key="any",
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
||||
):
|
||||
await hass.async_add_executor_job(
|
||||
ir.async_delete_issue,
|
||||
hass,
|
||||
"any",
|
||||
"any",
|
||||
)
|
||||
|
||||
|
||||
async def test_async_ignore_issue_thread_safety(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test call async_ignore_issue from a thread."""
|
||||
ir.async_create_issue(
|
||||
hass,
|
||||
"any",
|
||||
"any",
|
||||
is_fixable=True,
|
||||
severity="error",
|
||||
translation_key="any",
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match="Detected code that calls async_ignore from a thread. Please report this issue.",
|
||||
):
|
||||
await hass.async_add_executor_job(
|
||||
ir.async_ignore_issue, hass, "any", "any", True
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue