Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement command priority #237

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ readme = "README.md"
license = {text = "GPL-3.0"}
requires-python = ">=3.8"
dependencies = [
"zigpy>=0.60.0",
"zigpy>=0.60.2",
"async_timeout",
"voluptuous",
"coloredlogs",
Expand Down
26 changes: 24 additions & 2 deletions zigpy_znp/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import zigpy.zdo.types as zdo_t
import zigpy.exceptions
from zigpy.exceptions import NetworkNotFormed
from zigpy.datastructures import PriorityLock

import zigpy_znp.const as const
import zigpy_znp.types as t
Expand Down Expand Up @@ -58,7 +59,7 @@ def __init__(self, config: conf.ConfigType):
self._config = config

self._listeners = defaultdict(list)
self._sync_request_lock = asyncio.Lock()
self._sync_request_lock = PriorityLock()

self.capabilities = None # type: int
self.version = None # type: float
Expand Down Expand Up @@ -963,6 +964,27 @@ def wait_for_response(self, response: t.CommandBase) -> asyncio.Future:

return self.wait_for_responses([response])

def get_request_priority(self, request: t.CommandBase) -> int:
"""
Returns the priority of a request.
"""

return {
# Reset requests always take priority
c.SYS.ResetReq.Req: 9999,
# Watchdog pings are a close second
c.SYS.Ping.Req: 9998,
# Network requests are deprioritized
c.ZDO.ExtRouteChk.Req: -1,
c.ZDO.ExtRouteDisc.Req: -1,
c.UTIL.AssocGetWithAddress.Req: -1,
c.UTIL.AssocRemove.Req: -1,
c.UTIL.AssocAdd.Req: -1,
c.AF.DataRequestExt.Req: -1,
c.AF.DataRequestSrcRtg.Req: -1,
c.ZDO.MgmtPermitJoinReq.Req: -1,
}.get(type(request), 0)

async def request(
self, request: t.CommandBase, timeout: int | None = None, **response_params
) -> t.CommandBase | None:
Expand Down Expand Up @@ -1004,7 +1026,7 @@ async def request(
ctx = (
contextlib.AsyncExitStack()
if isinstance(request, c.SYS.ResetReq.Req)
else self._sync_request_lock
else self._sync_request_lock(priority=self.get_request_priority(request))
)

# We should only be sending one SREQ at a time, according to the spec
Expand Down