Source code for

#!/usr/bin/env python
import logging
import sys
import signal
from twisted.internet import reactor
from twisted.internet.error import ConnectionRefusedError, CannotListenError
from twisted.spread import pb

from simulaqron.cqc_backend.cqcFactory import CQCFactory
from simulaqron.cqc_backend.cqcMessageHandler import SimulaqronCQCHandler
from simulaqron.general.hostConfig import socketsConfig
from simulaqron.settings import simulaqron_settings

[docs]def init_register(virtRoot, myName, node): """Retrieves the relevant root objects to talk to such remote connections""" logging.debug("LOCAL %s: All connections set up.", myName) # Set the virtual node node.set_virtual_node(virtRoot) # Start listening to CQC messages setup_CQC_server(myName, node)
[docs]def connect_to_virtNode(myName, cqc_factory, virtualNet): """Trys to connect to local virtual node. If connection is refused, we try again after a set amount of time (specified in handle_connection_error) """ logging.debug("LOCAL %s: Trying to connect to local virtual node.", myName) virtual_node = virtualNet.hostDict[myName] factory = pb.PBClientFactory() # Connect reactor.connectTCP(virtual_node.hostname, virtual_node.port, factory) deferVirtual = factory.getRootObject() # If connection succeeds do: deferVirtual.addCallback(init_register, myName, cqc_factory) # If connection fails do: deferVirtual.addErrback(handle_connection_error, myName, cqc_factory, virtualNet)
[docs]def handle_connection_error(reason, myName, cqc_factory, virtualNet): """ Handles errors from trying to connect to local virtual node. If a ConnectionRefusedError is raised another try will be made after Settings.CONF_WAIT_TIME seconds. Any other error is raised again. """ try: reason.raiseException() except ConnectionRefusedError: logging.debug("LOCAL %s: Could not connect, trying again...", myName) reactor.callLater( simulaqron_settings.conn_retry_time, connect_to_virtNode, myName, cqc_factory, virtualNet, ) except Exception as e: logging.error( "LOCAL %s: Critical error when connection to local virtual node: %s", myName, e, ) reactor.stop()
[docs]def setup_CQC_server(myName, cqc_factory): """Setup CQC server to handle remote on the classical communication network.""" try: logging.debug( "LOCAL %s: Starting local classical communication server.", myName ) myHost = myHost.root = cqc_factory myHost.factory = cqc_factory reactor.listenTCP(myHost.port, myHost.factory) except CannotListenError: logging.error( "LOCAL {}: CQC server address ({}) is already in use.".format( myName, myHost.port ) ) reactor.stop() except Exception as e: logging.error( "LOCAL {}: Critical error when starting CQC server: {}".format(myName, e) ) reactor.stop()
[docs]def sigterm_handler(_signo, _stack_frame): reactor.stop()
[docs]def main(myName, network_name="default"): """Start the indicated backend CQC Server""" signal.signal(signal.SIGTERM, sigterm_handler) signal.signal(signal.SIGINT, sigterm_handler) logging.basicConfig( format="%(asctime)s:%(levelname)s:%(message)s", level=simulaqron_settings.log_level, ) if simulaqron_settings.network_config_file is not None: # Since version 3.0.0 a single config file is used virtualFile = simulaqron_settings.network_config_file cqcFile = simulaqron_settings.network_config_file else: # This file defines the network of virtual quantum nodes virtualFile = simulaqron_settings.vnode_file # This file defines the network of CQC servers interfacing to virtual quantum nodes cqcFile = simulaqron_settings.cqc_file # Read configuration files for the virtual quantum, as well as the classical network virtualNet = socketsConfig(virtualFile, network_name=network_name, config_type="vnode") cqcNet = socketsConfig(cqcFile, network_name=network_name, config_type="cqc") # Check if we are in the host-dictionary if myName in cqcNet.hostDict: myHost = cqcNet.hostDict[myName] cqc_factory = CQCFactory(myHost, myName, cqcNet, SimulaqronCQCHandler, network_name=network_name) else: logging.error("LOCAL %s: Cannot start classical communication servers.", myName) return # Connect to the local virtual node simulating the "local" qubits connect_to_virtNode(myName, cqc_factory, virtualNet) # Run reactor
if __name__ == '__main__': main(sys.argv[1])