Skip to content

Commit

Permalink
Merge pull request #353 from palfrey/one-api-call-at-a-time
Browse files Browse the repository at this point in the history
Uses a Semaphore to limit API calls to one at a time to avoid KLF issues
  • Loading branch information
pawlizio committed Nov 27, 2023
2 parents dd2009f + d25c6de commit 0a28367
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
18 changes: 12 additions & 6 deletions pyvlx/api/api_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ def __init__(self, pyvlx: "PyVLX", timeout_in_seconds: int = 10):

async def do_api_call(self) -> None:
"""Start. Sending and waiting for answer."""
self.pyvlx.connection.register_frame_received_cb(self.response_rec_callback)
await self.send_frame()
await self.start_timeout()
await self.response_received_or_timeout.wait()
await self.stop_timeout()
self.pyvlx.connection.unregister_frame_received_cb(self.response_rec_callback)
# We check for connection before entering the semaphore section
# because otherwise we might try to connect, which calls this, and we get stuck on
# the semaphore.
await self.pyvlx.check_connected()

async with self.pyvlx.api_call_semaphore:
self.pyvlx.connection.register_frame_received_cb(self.response_rec_callback)
await self.send_frame()
await self.start_timeout()
await self.response_received_or_timeout.wait()
await self.stop_timeout()
self.pyvlx.connection.unregister_frame_received_cb(self.response_rec_callback)

async def handle_frame(self, frame: FrameBase) -> bool:
"""Handle incoming API frame, return True if this was the expected frame."""
Expand Down
2 changes: 1 addition & 1 deletion pyvlx/api/get_all_nodes_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class GetAllNodesInformation(ApiEvent):
"""Class for retrieving node informationfrom API."""
"""Class for retrieving node information from API."""

def __init__(self, pyvlx: "PyVLX"):
"""Initialize SceneList class."""
Expand Down
9 changes: 7 additions & 2 deletions pyvlx/pyvlx.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(self,
self.version = None
self.protocol_version = None
self.klf200 = Klf200Gateway(pyvlx=self)
self.api_call_semaphore = asyncio.Semaphore(1) # Limit parallel commands

async def connect(self) -> None:
"""Connect to KLF 200."""
Expand All @@ -67,10 +68,14 @@ async def reboot_gateway(self) -> None:
PYVLXLOG.warning("KLF 200 reboot initiated")
await self.klf200.reboot()

async def send_frame(self, frame: FrameBase) -> None:
"""Send frame to API via connection."""
async def check_connected(self) -> None:
"""Check we're connected, and if not, connect."""
if not self.connection.connected:
await self.connect()

async def send_frame(self, frame: FrameBase) -> None:
"""Send frame to API via connection."""
await self.check_connected()
self.connection.write(frame)

async def disconnect(self) -> None:
Expand Down

0 comments on commit 0a28367

Please sign in to comment.