Skip to content

Commit

Permalink
Add start_server to run a capnp server
Browse files Browse the repository at this point in the history
The method `start_server` allows starting the capnp server with
schema and server instance. It enables the creation of
stand-alone Python servers accepting multiple connections.
  • Loading branch information
Remi Mommsen authored and tobiasah committed Mar 21, 2024
1 parent 5da0599 commit 23444ef
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/labone/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This subpackage allows to create a data server through capnp.
"""

from labone.server.server import CapnpServer
from labone.server.server import CapnpServer, start_server
from labone.server.session import (
SessionFunctionality,
SessionInterface,
Expand All @@ -12,6 +12,7 @@

__all__ = [
"CapnpServer",
"start_server",
"SessionFunctionality",
"SessionInterface",
"Subscription",
Expand Down
47 changes: 47 additions & 0 deletions src/labone/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

from __future__ import annotations

import argparse
import asyncio
import socket
from abc import ABC
from contextlib import suppress
from typing import TYPE_CHECKING

import capnp
Expand Down Expand Up @@ -132,3 +135,47 @@ async def start_local_server(
writer = await capnp.AsyncIoStream.create_connection(sock=write)
# create server for the local socket pair
return capnp_server_factory(writer, schema, server), reader


def start_server(
schema: CapnpStructReader,
server: CapnpServer,
) -> None:
"""Start the server.
Start the capnp server with the given schema and server instance.
The server address and port can be specified via command line arguments.
The server keeps running until it is interrupted.
Args:
schema: Parsed capnp schema (`reflection_capnp.CapSchema`).
server: The concrete server implementation.
"""

def _host_port() -> tuple[str, int]:
parser = argparse.ArgumentParser(
usage="""Runs the server bound to the given address/port ADDRESS. """,
)

parser.add_argument("address", help="ADDRESS:PORT")

return parser.parse_args().address.split(":")

async def _new_connection(
stream: capnp.AsyncIoStream,
) -> None:
await capnp_server_factory(
stream=stream,
schema=schema,
server=server,
).on_disconnect()

async def _run_server() -> None:
await ensure_capnp_event_loop()
host, port = _host_port()
server = await capnp.AsyncIoStream.create_server(_new_connection, host, port)
async with server:
await server.serve_forever()

with suppress(KeyboardInterrupt):
asyncio.run(_run_server())

0 comments on commit 23444ef

Please sign in to comment.