Chromium Code Reviews| Index: testing/legion/discovery_server.py |
| diff --git a/testing/legion/discovery_server.py b/testing/legion/discovery_server.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6b5267313a4d61418055b7a11014ec8ffcfe0be9 |
| --- /dev/null |
| +++ b/testing/legion/discovery_server.py |
| @@ -0,0 +1,86 @@ |
| +# Copyright 2015 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| +"""The discovery server used to register clients. |
| + |
| +The discovery server is started by the host controller and allows the clients |
| +to register themselves when they start. Authentication of the client controllers |
| +is based on an OTP passed to the client controller binary on startup. |
| +""" |
| + |
| +import logging |
| +import threading |
| +import xmlrpclib |
| +import SimpleXMLRPCServer |
| + |
| +SERVER_ADDRESS = '' |
| +SERVER_PORT = 31710 |
| + |
| + |
| +class DiscoveryServer(object): |
| + """Discovery server run on the host.""" |
| + |
| + def __init__(self): |
| + self._expected_clients = {} |
| + self._rpc_server = None |
| + self._thread = None |
| + |
| + def _RegisterClientRPC(self, otp, ip): |
| + """The RPC used by a client to register with the discovery server. |
| + |
| + Args: |
| + otp: The one time token issued by the host. |
| + ip: The ip address of the client. |
| + |
| + Raises: |
| + KeyError if the OTP isn't found in _expected_clients |
| + """ |
| + if otp not in self._expected_clients: |
| + raise KeyError('OTP not found') |
| + cb = self._expected_clients[otp] |
|
Marc-Antoine Ruel (Google)
2015/01/30 21:58:40
You mean:
cb = self._expected_clients.pop(otp)
cb
Mike Meade
2015/02/03 01:18:09
Done.
|
| + del self._expected_clients[otp] |
| + cb(ip) |
| + |
| + def RegisterClientCallback(self, otp, callback): |
| + """Registers a callback associated with an OTP. |
| + |
| + Args: |
| + otp: A one time token used by the client to authenticate. |
| + callback: The callback used when the client connects. |
| + |
| + Raises: |
| + TypeError if the callback is not callable. |
| + """ |
| + if not callable(callback): |
|
Marc-Antoine Ruel (Google)
2015/01/30 21:58:40
use an assert, it's not something normal.
Mike Meade
2015/02/03 01:18:09
Done.
|
| + raise TypeError('callback is not callable') |
| + self._expected_clients[otp] = callback |
| + |
| + def Start(self, address=None, port=None): |
|
Marc-Antoine Ruel (Google)
2015/01/30 21:58:40
*args, **kwargs again
Mike Meade
2015/02/03 01:18:09
Changed this around. I hard coded the address and
|
| + """Starts the discovery server. |
| + |
| + Args: |
| + address: The address to run the server on ('', 'localhost', etc). |
| + port: The port to run the server on. |
| + """ |
| + address = address or SERVER_ADDRESS |
|
Marc-Antoine Ruel (Google)
2015/01/30 21:58:40
I don't like these to be sprinkled at multiple pla
Mike Meade
2015/02/03 01:18:09
Moved all references to address and port to common
|
| + port = port = SERVER_PORT |
| + logging.debug('Starting discovery server') |
| + self._rpc_server = SimpleXMLRPCServer.SimpleXMLRPCServer( |
| + (address, port), allow_none=True, logRequests=False) |
| + self._rpc_server.register_function( |
| + self._RegisterClientRPC, 'RegisterClient') |
| + self._thread = threading.Thread(target=self._rpc_server.serve_forever) |
| + self._thread.start() |
| + |
| + def Shutdown(self): |
| + """Shuts the discovery server down.""" |
| + if self._thread and self._thread.is_alive(): |
| + logging.debug('Shutting down discovery server') |
| + self._rpc_server.shutdown() |
| + |
| + @staticmethod |
| + def Connect(host): |
|
Marc-Antoine Ruel (Google)
2015/01/30 21:58:40
What's the relationship with the class? Why is it
Mike Meade
2015/02/03 01:18:09
Moved this and the other "Connect" method to commo
|
| + """Create a connection to the discovery server.""" |
| + server = 'http://%s:%s' % (host, SERVER_PORT) |
| + logging.info('Connecting to a discovery server at %s', server) |
| + return xmlrpclib.Server(server) |