Skip to content

Commit

Permalink
more playing with async
Browse files Browse the repository at this point in the history
  • Loading branch information
gijzelaerr committed Jul 4, 2024
1 parent e312086 commit c1fa224
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 12 deletions.
Empty file added snap7/asio/__init__.py
Empty file.
30 changes: 30 additions & 0 deletions snap7/asio/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from functools import partial
from snap7.client import Client
from asyncio import get_running_loop
from concurrent.futures import ThreadPoolExecutor


class AsyncClient:
def __await__(self) -> "AsyncClient":
return self

def __init__(self) -> None:
self.client = Client()
self.loop = get_running_loop()
self.pool = ThreadPoolExecutor()

async def disconnect(self) -> None:
await self.loop.run_in_executor(self.pool, lambda: self.client.disconnect)

async def destroy(self) -> None:
await self.loop.run_in_executor(self.pool, lambda: self.client.destroy)

async def db_write(self, db_number: int, start: int, data: bytearray) -> int:
# func: Callable[[], int] = lambda: self.client.db_write(db_number, start, data)
func = partial(self.client.db_write, db_number, start, data)
result: int = await self.loop.run_in_executor(self.pool, func) # type: ignore
return result

async def db_get(self, db_number: int) -> bytearray:
result: bytearray = await self.loop.run_in_executor(self.pool, lambda: self.client.db_get(db_number))
return result
42 changes: 42 additions & 0 deletions tests/test_async_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from snap7.asio.client import AsyncClient
from snap7.server import mainloop
from unittest import IsolatedAsyncioTestCase, main
from multiprocessing import Process
from time import sleep


class AsyncClientTest(IsolatedAsyncioTestCase):
process = None

@classmethod
def setUpClass(cls) -> None:
cls.process = Process(target=mainloop)
cls.process.start()
sleep(2) # wait for server to start

@classmethod
def tearDownClass(cls) -> None:
if cls.process:
cls.process.terminate()
cls.process.join(1)
if cls.process.is_alive():
cls.process.kill()

async def asyncSetUp(self) -> None:
self.client = AsyncClient()

async def asyncTearDown(self) -> None:
await self.client.disconnect()
await self.client.destroy()

async def test_db_write(self) -> None:
size = 40
data = bytearray(size)
await self.client.db_write(db_number=1, start=0, data=data)

async def test_db_get(self) -> None:
await self.client.db_get(db_number=1)


if __name__ == "__main__":
main()
12 changes: 0 additions & 12 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,6 @@ def tearDown(self) -> None:
self.client.disconnect()
self.client.destroy()

def _as_check_loop(self, check_times: int = 20) -> int:
check_status = c_int(-1)
# preparing Server values
for i in range(check_times):
self.client.check_as_completion(check_status)
if check_status.value == 0:
break
time.sleep(0.5)
else:
raise TimeoutError(f"Async Request not finished after {check_times} times - Fail")
return check_status.value

def test_db_read(self) -> None:
size = 40
start = 0
Expand Down

0 comments on commit c1fa224

Please sign in to comment.