diff --git a/pyproject.toml b/pyproject.toml index 28fc595..178ac52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "qat-rpc" -version = "0.5.0" +version = "0.6.0" description = "RPC tooling for OQC QAT." authors = ["Kajsa Eriksson Rosenqvist "] readme = "README.md" diff --git a/src/QAT_RPC/qat_rpc/utils/metrics.py b/src/QAT_RPC/qat_rpc/utils/metrics.py index c7d4e14..594e547 100644 --- a/src/QAT_RPC/qat_rpc/utils/metrics.py +++ b/src/QAT_RPC/qat_rpc/utils/metrics.py @@ -84,10 +84,13 @@ def hardware_reloaded(self, outcome: BinaryMutableOutcome): ... class PrometheusReceiver(ReceiverBackend): - def __init__(self, port: int): + def __init__( + self, + port: int = PROMETHEUS_PORT + ): super(PrometheusReceiver, self).__init__() - start_http_server(port=PROMETHEUS_PORT) - log.info(f"Using Prometheus on port {port}") + start_http_server(port) + log.info(f"Starting Prometheus metrics exporter on port {port}.") self._receiver_status = Gauge( "receiver_status", "Measure the Receiver backend up state" diff --git a/src/QAT_RPC/qat_rpc/zmq/receiver.py b/src/QAT_RPC/qat_rpc/zmq/receiver.py index 576dc5c..ab876ba 100644 --- a/src/QAT_RPC/qat_rpc/zmq/receiver.py +++ b/src/QAT_RPC/qat_rpc/zmq/receiver.py @@ -27,7 +27,60 @@ def _sigterm(self, *args): def main(): hw = None - metric_exporter = MetricExporter(backend=PrometheusReceiver(PROMETHEUS_PORT)) + receiver_port = os.getenv("RECEIVER_PORT") + metrics_port = os.getenv("METRICS_PORT") + + if receiver_port is not None: + try: + int(receiver_port) + except ValueError: + log.warning("Configured receiver port is not a valid integer.") + receiver_port = 5556 + log.info(f"Defaulting receiver to run on port {receiver_port}") + else: + try: + if not (1024 < int(receiver_port) < 49152): + raise ValueError("Receiver must be configured to run on a valid port number between 1024 and 49152.") + log.info(f"Receiver server is configured to start on port {receiver_port}.") + except ValueError as e: + log.warning(f"{e}") + receiver_port = 5556 + log.info(f"Defaulting receiver to run on port {receiver_port}.") + else: + receiver_port = 5556 + + if metrics_port is not None: + try: + int(metrics_port) + except ValueError: + log.warning("Configured metrics port is not a valid integer.") + metrics_port = PROMETHEUS_PORT + log.info(f"Defaulting metrics exporter to run on port {metrics_port}") + else: + try: + if (int(metrics_port) == int(receiver_port)): + raise ValueError(f"Metrics exporter cannot run on port {metrics_port}, it must be set to a different value to the receiver port.") + elif not (1024 < int(metrics_port) < 49152): + raise ValueError("Metrics exporter must be configured to run on a valid port number between 1024 and 49152.") + log.info(f"Metrics exporter is configured to start on port {metrics_port}.") + except ValueError as e: + log.warning(f"{e}") + metrics_port = PROMETHEUS_PORT + log.info(f"Defaulting metrics exporter to run on port {metrics_port}.") + else: + metrics_port = PROMETHEUS_PORT + + try: + if int(metrics_port) == int(receiver_port): + raise ValueError + except ValueError: + log.warning("The receiver and metrics exporter have been configured to run on the same port.") + receiver_port = 5556 + metrics_port = PROMETHEUS_PORT + log.info(f"Defaulting receiver to run on port {receiver_port} and metrics exporter to run on port {metrics_port}.") + + metric_exporter = MetricExporter(backend=PrometheusReceiver(port=int(metrics_port))) + if (calibration_file := os.getenv("TOSHIKO_CAL")) is not None: calibration_file = Path(calibration_file) if not calibration_file.is_absolute() and not calibration_file.is_file(): @@ -38,10 +91,10 @@ def main(): hw = Calibratable.load_calibration_from_file(str(calibration_file)) log.debug("Loaded") - receiver = ZMQServer(hardware=hw, metric_exporter=metric_exporter) + receiver = ZMQServer(hardware=hw, server_port=receiver_port, metric_exporter=metric_exporter) gk = GracefulKill(receiver) - log.info(f"Starting receiver with {type(receiver._hardware)} hardware.") + log.info(f"Starting QAT receiver on port {str(receiver._port)} with {type(receiver._hardware)} hardware.") receiver.run() diff --git a/src/QAT_RPC/qat_rpc/zmq/wrappers.py b/src/QAT_RPC/qat_rpc/zmq/wrappers.py index b0dc171..168a081 100644 --- a/src/QAT_RPC/qat_rpc/zmq/wrappers.py +++ b/src/QAT_RPC/qat_rpc/zmq/wrappers.py @@ -24,7 +24,10 @@ class Messages(Enum): class ZMQBase: def __init__( - self, socket_type: zmq.SocketType, ip_address: str = "127.0.0.1", port: str = "5556" + self, + socket_type: zmq.SocketType, + ip_address: str = "127.0.0.1", + port: str = "5556" ): self._context = zmq.Context() self._socket = self._context.socket(socket_type) @@ -73,9 +76,10 @@ class ZMQServer(ZMQBase): def __init__( self, hardware: Optional[QuantumHardwareModel] = None, - metric_exporter: Optional[MetricExporter] = None, + server_port: Optional[str] = None, + metric_exporter: Optional[MetricExporter] = None ): - super().__init__(zmq.REP) + super().__init__(socket_type=zmq.REP, port=server_port) self._metric = metric_exporter self._socket.bind(self.address) self._hardware = hardware or get_default_echo_hardware(qubit_count=32) @@ -157,8 +161,12 @@ def stop(self): class ZMQClient(ZMQBase): - def __init__(self, ip_address: str = "127.0.0.1", port: str = "5556"): - super().__init__(zmq.REQ, ip_address, port) + def __init__( + self, + client_ip: Optional[str] = None, + client_port: Optional[str] = None + ): + super().__init__(socket_type=zmq.REQ, ip_address=client_ip, port=client_port) self._socket.setsockopt(zmq.LINGER, 0) self._socket.connect(self.address)