mirror of https://github.com/m-labs/artiq.git
pc_rpc/Server: add built-in terminate
This commit is contained in:
parent
a21049d779
commit
4b195663f6
|
@ -240,7 +240,8 @@ class BestEffortClient:
|
|||
network errors are suppressed and connections are retried in the
|
||||
background.
|
||||
|
||||
RPC calls that failed because of network errors return ``None``.
|
||||
RPC calls that failed because of network errors return ``None``. Other RPC
|
||||
calls are blocking and return the correct value.
|
||||
|
||||
:param firstcon_timeout: Timeout to use during the first (blocking)
|
||||
connection attempt at object initialization.
|
||||
|
@ -397,12 +398,19 @@ class Server(_AsyncioServer):
|
|||
exposed to the client. Keys are names identifying each object.
|
||||
Clients select one of these objects using its name upon connection.
|
||||
:param id_parameters: An optional human-readable string giving more
|
||||
information about the parameters of the server.
|
||||
information about the server.
|
||||
:param builtin_terminate: If set, the server provides a built-in
|
||||
``terminate`` method that unblocks any tasks waiting on
|
||||
``wait_terminate``. This is useful to handle server termination
|
||||
requests from clients.
|
||||
"""
|
||||
def __init__(self, targets, id_parameters=None):
|
||||
def __init__(self, targets, id_parameters=None, builtin_terminate=False):
|
||||
_AsyncioServer.__init__(self)
|
||||
self.targets = targets
|
||||
self.id_parameters = id_parameters
|
||||
self.builtin_terminate = builtin_terminate
|
||||
if builtin_terminate:
|
||||
self._terminate_request = asyncio.Event()
|
||||
|
||||
@asyncio.coroutine
|
||||
def _handle_connection_cr(self, reader, writer):
|
||||
|
@ -448,9 +456,13 @@ class Server(_AsyncioServer):
|
|||
obj = {"status": "ok", "ret": doc}
|
||||
elif obj["action"] == "call":
|
||||
logger.debug("calling %s", _PrettyPrintCall(obj))
|
||||
method = getattr(target, obj["name"])
|
||||
ret = method(*obj["args"], **obj["kwargs"])
|
||||
obj = {"status": "ok", "ret": ret}
|
||||
if self.builtin_terminate and obj["name"] == "terminate":
|
||||
self._terminate_request.set()
|
||||
obj = {"status": "ok", "ret": None}
|
||||
else:
|
||||
method = getattr(target, obj["name"])
|
||||
ret = method(*obj["args"], **obj["kwargs"])
|
||||
obj = {"status": "ok", "ret": ret}
|
||||
else:
|
||||
raise ValueError("Unknown action: {}"
|
||||
.format(obj["action"]))
|
||||
|
@ -462,18 +474,23 @@ class Server(_AsyncioServer):
|
|||
finally:
|
||||
writer.close()
|
||||
|
||||
@asyncio.coroutine
|
||||
def wait_terminate(self):
|
||||
yield from self._terminate_request.wait()
|
||||
|
||||
|
||||
def simple_server_loop(targets, host, port, id_parameters=None):
|
||||
"""Runs a server until an exception is raised (e.g. the user hits Ctrl-C).
|
||||
"""Runs a server until an exception is raised (e.g. the user hits Ctrl-C)
|
||||
or termination is requested by a client.
|
||||
|
||||
See ``Server`` for a description of the parameters.
|
||||
"""
|
||||
loop = asyncio.get_event_loop()
|
||||
try:
|
||||
server = Server(targets, id_parameters)
|
||||
server = Server(targets, id_parameters, True)
|
||||
loop.run_until_complete(server.start(host, port))
|
||||
try:
|
||||
loop.run_forever()
|
||||
loop.run_until_complete(server.wait_terminate())
|
||||
finally:
|
||||
loop.run_until_complete(server.stop())
|
||||
finally:
|
||||
|
|
Loading…
Reference in New Issue