Esempio n. 1
0
 def __init__(self):
     self.info = IPCServerInfoWindow()
     self.senders = {}
     self.receivers = {}
     self.widgets = {}
     self.protocol_map = {}
     self.processor = CommandProcessor()
Esempio n. 2
0
 def __init__(self):
     self.info = IPCServerInfoWindow()
     self.senders = {}
     self.receivers = {}
     self.widgets = {}
     self.protocol_map = {}
     self.processor = CommandProcessor()
Esempio n. 3
0
class IPCFacade(with_metaclass(Singleton, object)):
    """
    The Singleton that encapsulates all IPC functionality
    Use this to register new server modules or send broadcasts
    """
    def __init__(self):
        self.info = IPCServerInfoWindow()
        self.senders = {}
        self.receivers = {}
        self.widgets = {}
        self.protocol_map = {}
        self.processor = CommandProcessor()

    def register_shell(self, shell):
        """
        This sets the shell. Must be called before incoming command can be executed
        :param shell: the ilastik shell
        """
        self.processor.set_shell(shell)

    def register_widget(self, widget, title, key):
        """
        Add a new widget to the IPCServerWindow
        :param widget: the widget to add
        :param title: the title to appear in the tab bar
        :param key: the key to identify and reference the widget
        """
        if key in self.widgets:
            raise RuntimeError("Widget {} already exists".format(key))
        self.widgets[key] = widget
        self.info.add_widget(title, widget)

    def register_module(self,
                        module,
                        type_,
                        key,
                        widget_key=None,
                        protocol=None,
                        start=False):
        """
        Adds a new module to the IPCServer
        :param module: the module e.g. TCPServer, ZMQPublisher
        :param type_: "sender" or "receiver"
        :param key: the key to identify the module later
        :param widget_key: a reference to the view widget. If not None the module will connect to it
        :param protocol: set this to redirect handshake command with the matching protocol to this module
        :param start: if set the module will start immediately
        """
        if type_ == "receiver":
            container = self.receivers
            self.processor.connect_receiver(module)
        elif type_ == "sender":
            container = self.senders
        else:
            raise RuntimeError("Type {} is invalid".format(type_))

        if key in container:
            raise RuntimeError("{} {} already exists".format(type_, key))
        container[key] = module
        if widget_key is not None:
            module.connect_widget(self.widgets[widget_key])
        if protocol is not None:
            self.protocol_map[protocol] = module

        if start:
            module.start()

    def handshake(self, protocol, name, address):
        """
        Redirects a handshake command to the registered module
        Currently only TCPClient handles handshake commands from TCPServer
        :param protocol: the protocol to identify the handler ( e.g. tcp )
        :param name: the name of the peer ( e.g. KNIME )
        :param address: the address of the peer. Depends on the protocol ( e.g. for tcp => (str: host, int: port)
        """
        if protocol not in self.protocol_map:
            raise RuntimeError("No such protocol {}".format(protocol))
        self.protocol_map[protocol].add_peer(name, address)

    @property
    def sending(self):
        """
        Check if the senders are running ( e.g. any(IPCFacade().running) or all(IPCFacade().running)
        :return: a list containing True or False for each sender
        """
        return (sender.running for sender in self.senders.values())

    @property
    def receiving(self):
        """
        The same as IPCFacade.sending for the receivers
        """
        return (rec.running for rec in self.receivers.values())

    def start(self):
        """
        Start all registered modules
        """
        for module in self._all_modules():
            module.start()

    def stop(self):
        """
        Stop all registered modules
        """
        for module in self._all_modules():
            module.stop()

    def _all_modules(self):
        return chain(iter(self.senders.values()),
                     iter(self.receivers.values()))

    @lazy
    def broadcast(self, command):
        """
        Creates functions that can directly be passed to Qt's connect mechanism
        e.g.
            action = IPCFacade().broadcast( ... a command ... )
            qtSignal.connect(action)
        :param command: the command ( dict )
        """
        # from pprint import PrettyPrinter
        # PrettyPrinter(indent=4).pprint(command)
        message = json.dumps(command, cls=NumpyJsonEncoder)
        log = Protocol.verbose(command)
        for server in self.senders.values():
            server.broadcast(message, log)

    def show_info(self):
        """
        Displays the IPC Info Widget or moves the windows to the top
        :return:
        """
        self.info.show()
        self.info.activateWindow()  # bring to top
Esempio n. 4
0
class IPCFacade(with_metaclass(Singleton, object)):
    """
    The Singleton that encapsulates all IPC functionality
    Use this to register new server modules or send broadcasts
    """

    def __init__(self):
        self.info = IPCServerInfoWindow()
        self.senders = {}
        self.receivers = {}
        self.widgets = {}
        self.protocol_map = {}
        self.processor = CommandProcessor()

    def register_shell(self, shell):
        """
        This sets the shell. Must be called before incoming command can be executed
        :param shell: the ilastik shell
        """
        self.processor.set_shell(shell)

    def register_widget(self, widget, title, key):
        """
        Add a new widget to the IPCServerWindow
        :param widget: the widget to add
        :param title: the title to appear in the tab bar
        :param key: the key to identify and reference the widget
        """
        if key in self.widgets:
            raise RuntimeError("Widget {} already exists".format(key))
        self.widgets[key] = widget
        self.info.add_widget(title, widget)

    def register_module(self, module, type_, key, widget_key=None, protocol=None, start=False):
        """
        Adds a new module to the IPCServer
        :param module: the module e.g. TCPServer, ZMQPublisher
        :param type_: "sender" or "receiver"
        :param key: the key to identify the module later
        :param widget_key: a reference to the view widget. If not None the module will connect to it
        :param protocol: set this to redirect handshake command with the matching protocol to this module
        :param start: if set the module will start immediately
        """
        if type_ == "receiver":
            container = self.receivers
            self.processor.connect_receiver(module)
        elif type_ == "sender":
            container = self.senders
        else:
            raise RuntimeError("Type {} is invalid".format(type_))

        if key in container:
            raise RuntimeError("{} {} already exists".format(type_, key))
        container[key] = module
        if widget_key is not None:
            module.connect_widget(self.widgets[widget_key])
        if protocol is not None:
            self.protocol_map[protocol] = module

        if start:
            module.start()

    def handshake(self, protocol, name, address):
        """
        Redirects a handshake command to the registered module
        Currently only TCPClient handles handshake commands from TCPServer
        :param protocol: the protocol to identify the handler ( e.g. tcp )
        :param name: the name of the peer ( e.g. KNIME )
        :param address: the address of the peer. Depends on the protocol ( e.g. for tcp => (str: host, int: port)
        """
        if protocol not in self.protocol_map:
            raise RuntimeError("No such protocol {}".format(protocol))
        self.protocol_map[protocol].add_peer(name, address)

    @property
    def sending(self):
        """
        Check if the senders are running ( e.g. any(IPCFacade().running) or all(IPCFacade().running)
        :return: a list containing True or False for each sender
        """
        return (sender.running for sender in self.senders.values())

    @property
    def receiving(self):
        """
        The same as IPCFacade.sending for the receivers
        """
        return (rec.running for rec in self.receivers.values())

    def start(self):
        """
        Start all registered modules
        """
        for module in self._all_modules():
            module.start()

    def stop(self):
        """
        Stop all registered modules
        """
        for module in self._all_modules():
            module.stop()

    def _all_modules(self):
        return chain(iter(self.senders.values()), iter(self.receivers.values()))

    @lazy
    def broadcast(self, command):
        """
        Creates functions that can directly be passed to Qt's connect mechanism
        e.g.
            action = IPCFacade().broadcast( ... a command ... )
            qtSignal.connect(action)
        :param command: the command ( dict )
        """
        #from pprint import PrettyPrinter
        #PrettyPrinter(indent=4).pprint(command)
        message = json.dumps(command, cls=NumpyJsonEncoder)
        log = Protocol.verbose(command)
        for server in self.senders.values():
            server.broadcast(message, log)

    def show_info(self):
        """
        Displays the IPC Info Widget or moves the windows to the top
        :return:
        """
        self.info.show()
        self.info.activateWindow()  # bring to top