windows named pipe support for python

This commit is contained in:
John Smith 2023-12-16 12:46:57 -05:00 committed by Christien Rioux
parent 6bfe9a0236
commit 4e36524778
2 changed files with 36 additions and 10 deletions

View File

@ -32,6 +32,15 @@ def server_info() -> tuple[str, int]:
return hostname, int(rest[0]) return hostname, int(rest[0])
return hostname, 5959 return hostname, 5959
def ipc_path_exists(path: str) -> bool:
"""Determine if an IPC socket exists in a platform independent way."""
if os.name == 'nt':
if not path.upper().startswith("\\\\.\\PIPE\\"):
return False
return path[9:] in os.listdir("\\\\.\\PIPE")
else:
return os.path.exists(path)
@cache @cache
def ipc_info() -> str: def ipc_info() -> str:
"""Return the path of the ipc socket of the test server.""" """Return the path of the ipc socket of the test server."""
@ -40,12 +49,11 @@ def ipc_info() -> str:
return VEILID_SERVER_IPC return VEILID_SERVER_IPC
if os.name == 'nt': if os.name == 'nt':
return '\\\\.\\PIPE\\veilid-server\\ipc\\0' return '\\\\.\\PIPE\\veilid-server\\0'
if os.name == 'posix': ipc_0_path = "/var/db/veilid-server/ipc/0"
ipc_0_path = "/var/db/veilid-server/ipc/0" if os.path.exists(ipc_0_path):
if os.path.exists(ipc_0_path): return ipc_0_path
return ipc_0_path
# hack to deal with rust's 'directories' crate case-inconsistency # hack to deal with rust's 'directories' crate case-inconsistency
if sys.platform.startswith('darwin'): if sys.platform.startswith('darwin'):
@ -67,8 +75,7 @@ async def api_connector(callback: Callable) -> _JsonVeilidAPI:
hostname, port = server_info() hostname, port = server_info()
try: try:
print(f"ipc_path: {ipc_path}") if ipc_path_exists(ipc_path):
if os.path.exists(ipc_path):
return await veilid.json_api_connect_ipc(ipc_path, callback) return await veilid.json_api_connect_ipc(ipc_path, callback)
else: else:
return await veilid.json_api_connect(hostname, port, callback) return await veilid.json_api_connect(hostname, port, callback)

View File

@ -155,11 +155,30 @@ class _JsonVeilidAPI(VeilidAPI):
async def connect_ipc( async def connect_ipc(
cls, ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable] cls, ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable]
) -> Self: ) -> Self:
reader, writer = await asyncio.open_unix_connection(ipc_path) print("opening pipe")
if os.name=='nt':
async def open_windows_pipe(path=None, *,
limit=65536, **kwds):
"""Similar to `open_unix_connection` but works with Windows Named Pipes."""
loop = asyncio.events.get_running_loop()
reader = asyncio.StreamReader(limit=limit, loop=loop)
protocol = asyncio.StreamReaderProtocol(reader, loop=loop)
transport, _ = await loop.create_pipe_connection(
lambda: protocol, path, **kwds)
writer = asyncio.StreamWriter(transport, protocol, reader, loop)
return reader, writer
reader, writer = await open_windows_pipe(ipc_path)
else:
reader, writer = await asyncio.open_unix_connection(ipc_path)
print(f"reader: {vars(reader)}\nwriter: {vars(writer)}\n")
veilid_api = cls(reader, writer, update_callback) veilid_api = cls(reader, writer, update_callback)
veilid_api.handle_recv_messages_task = asyncio.create_task( veilid_api.handle_recv_messages_task = asyncio.create_task(
veilid_api.handle_recv_messages(), name="JsonVeilidAPI.handle_recv_messages" veilid_api.handle_recv_messages(), name="JsonVeilidAPI.handle_recv_messages"
) )
return veilid_api return veilid_api
async def handle_recv_message_response(self, j: dict): async def handle_recv_message_response(self, j: dict):