|
16 | 16 | import zigpy.zdo.types as zdo_t |
17 | 17 | import zigpy.exceptions |
18 | 18 | from zigpy.exceptions import NetworkNotFormed |
| 19 | +from zigpy.datastructures import PriorityLock |
19 | 20 |
|
20 | 21 | import zigpy_znp.const as const |
21 | 22 | import zigpy_znp.types as t |
@@ -58,7 +59,7 @@ def __init__(self, config: conf.ConfigType): |
58 | 59 | self._config = config |
59 | 60 |
|
60 | 61 | self._listeners = defaultdict(list) |
61 | | - self._sync_request_lock = asyncio.Lock() |
| 62 | + self._sync_request_lock = PriorityLock() |
62 | 63 |
|
63 | 64 | self.capabilities = None # type: int |
64 | 65 | self.version = None # type: float |
@@ -963,6 +964,27 @@ def wait_for_response(self, response: t.CommandBase) -> asyncio.Future: |
963 | 964 |
|
964 | 965 | return self.wait_for_responses([response]) |
965 | 966 |
|
| 967 | + def get_request_priority(self, request: t.CommandBase) -> int: |
| 968 | + """ |
| 969 | + Returns the priority of a request. |
| 970 | + """ |
| 971 | + |
| 972 | + return { |
| 973 | + # Reset requests always take priority |
| 974 | + c.SYS.ResetReq.Req: 9999, |
| 975 | + # Watchdog pings are a close second |
| 976 | + c.SYS.Ping.Req: 9998, |
| 977 | + # Network requests are deprioritized |
| 978 | + c.ZDO.ExtRouteChk.Req: -1, |
| 979 | + c.ZDO.ExtRouteDisc.Req: -1, |
| 980 | + c.UTIL.AssocGetWithAddress.Req: -1, |
| 981 | + c.UTIL.AssocRemove.Req: -1, |
| 982 | + c.UTIL.AssocAdd.Req: -1, |
| 983 | + c.AF.DataRequestExt.Req: -1, |
| 984 | + c.AF.DataRequestSrcRtg.Req: -1, |
| 985 | + c.ZDO.MgmtPermitJoinReq.Req: -1, |
| 986 | + }.get(type(request), 0) |
| 987 | + |
966 | 988 | async def request( |
967 | 989 | self, request: t.CommandBase, timeout: int | None = None, **response_params |
968 | 990 | ) -> t.CommandBase | None: |
@@ -1004,7 +1026,7 @@ async def request( |
1004 | 1026 | ctx = ( |
1005 | 1027 | contextlib.AsyncExitStack() |
1006 | 1028 | if isinstance(request, c.SYS.ResetReq.Req) |
1007 | | - else self._sync_request_lock |
| 1029 | + else self._sync_request_lock(priority=self.get_request_priority(request)) |
1008 | 1030 | ) |
1009 | 1031 |
|
1010 | 1032 | # We should only be sending one SREQ at a time, according to the spec |
|
0 commit comments