def test_stats_router(self):
        """
        Checking that the pool executor version of the router
        delivers signals as intended
        """
        from nio.common.block.router.stats_router import StatsRouter

        block_router = StatsRouter()
        context = BlockContext(block_router, dict(), dict(), None,
                               service_name="TestStatsRouterServiceName")

        # create blocks
        sender_block = BlockController(SenderBlock)
        sender_block.configure(context)
        receiver_block = BlockController(ReceiverBlock)
        receiver_block.configure(context)
        receiver_block2 = BlockController(ReceiverBlock2)
        receiver_block2.configure(context)

        # create a management subscriber
        subscriber = Subscriber(self._on_stats, **self._topics)
        subscriber.open()
        sleep(0.5)

        # create context initialization data
        receiver_blocks = 2
        blocks = AttributeDict(receiverblock=receiver_block,
                               receiverblock2=receiver_block2,
                               senderblock=sender_block)
        execution = [AttributeDict(name="senderblock",
                                   receivers=["receiverblock",
                                              "receiverblock2"])]

        router_context = RouterContext(execution, blocks)

        block_router.configure(router_context)
        block_router.start()

        signals_count = 0
        self._received_signals = 0
        for i in range(0, 50):
            signals = []
            for j in range(0, i):
                signals.append(j)
                signals_count += 1
            sender_block.process_signals(signals)
            sleep(0.02)
        sleep(0.1)
        self.assertEqual(signals_count * receiver_blocks,
                         self._received_signals)
        print('Received a total of: {0} signals'.
              format(self._received_signals))
        block_router.stop()
示例#2
0
class LocalSubscriber(GeneratorBlock):
    """ A block for subscribing to a local nio communication channel.

    Functions regardless of communication module implementation.

    Unlike the regular Subscriber block, the one does not need data to be json
    """
    version = VersionProperty("0.1.1")
    topic = StringProperty(title='Topic', default="")
    local_identifier = StringProperty(title='Local Identifier',
                                      default='[[INSTANCE_ID]]',
                                      visible=False)

    def __init__(self):
        super().__init__()
        self._subscriber = None

    def configure(self, context):
        super().configure(context)
        self._subscriber = NioSubscriber(self._subscriber_handler,
                                         topic="{}.{}".format(
                                             self.local_identifier(),
                                             self.topic()))

    def start(self):
        """ Start the block by opening the underlying subscriber """
        super().start()
        self._subscriber.open()

    def stop(self):
        """ Stop the block by closing the underlying subscriber """
        self._subscriber.close()
        super().stop()

    def _subscriber_handler(self, signals):
        try:
            signals = b64decode(signals[0].signals)
            signals = pickle.loads(signals)
        except pickle.UnpicklingError:
            self.logger.exception("Unpickling based pickle error")
        except TypeError:
            self.logger.exception("Unable to decode pickled signals")
        except:
            self.logger.exception("Error handling signals")
        else:
            self.notify_signals(signals)
示例#3
0
class Subscriber(Block):
    """ A block for subscribing to a NIO communication channel.

    Functions regardless of communication module implementation.

    Properties:
        topic (str): Defines topic to subscribe to in order to receive signals.

    """
    topic = StringProperty(title='Topic')

    def __init__(self):
        super().__init__()
        self._subscriber = None

    def configure(self, context):
        super().configure(context)
        self._subscriber = NIOSubscriber(self.process_signals,
                                         topic=self.topic())

    def start(self):
        """ Start the block by opening the underlying subscriber

        """
        super().start()
        self._subscriber.open()

    def stop(self):
        """ Stop the block by closing the underlying subscriber

        """
        self._subscriber.close()
        super().stop()

    def process_signals(self, signals):
        """ Subscriber block doesn't do any real processing. Just
        passes incoming signals along to any receivers.

        """
        self.notify_signals(signals)
 def _setup_pubsub(self):
     # Supscribe to published signals
     for publisher_topic in self.publisher_topics():
         self._subscribers[publisher_topic] = \
                 Subscriber(self._published_signals, topic=publisher_topic)
     for subscriber in self._subscribers:
         self._subscribers[subscriber].open()
     # Allow tests to publish to subscribers in service
     for subscriber_topic in self.subscriber_topics():
         self._publishers[subscriber_topic] = \
                 Publisher(topic=subscriber_topic)
     for publisher in self._publishers:
         self._publishers[publisher].open()
示例#5
0
class LocalSubscriber(PubSubConnectivity, GeneratorBlock):
    """ A block for subscribing to a local nio communication channel.

    Functions regardless of communication module implementation.

    Unlike the regular Subscriber block, the one does not need data to be json
    """
    version = VersionProperty("1.1.0")
    topic = StringProperty(title='Topic', default="")
    local_identifier = StringProperty(title='Local Identifier',
                                      default='[[INSTANCE_ID]]',
                                      visible=False)

    def __init__(self):
        super().__init__()
        self._subscriber = None

    def configure(self, context):
        super().configure(context)
        self._subscriber = NioSubscriber(self._subscriber_handler,
                                         topic="{}.{}".format(
                                             self.local_identifier(),
                                             self.topic()))

        try:
            self._subscriber.open(on_connected=self.conn_on_connected,
                                  on_disconnected=self.conn_on_disconnected)
        except TypeError as e:
            self.logger.warning(
                "Connecting to an outdated communication module")
            # try previous interface
            self._subscriber.open()
            # no need to configure connectivity if not supported
            return

        # let connectivity configure
        self.conn_configure(self._subscriber.is_connected)

    def stop(self):
        """ Stop the block by closing the underlying subscriber """
        self._subscriber.close()
        super().stop()

    def _subscriber_handler(self, signals):
        try:
            signals = b64decode(signals[0].signals)
            signals = pickle.loads(signals)
        except pickle.UnpicklingError:
            self.logger.exception("Unpickling based pickle error")
        except TypeError:
            self.logger.exception("Unable to decode pickled signals")
        except:
            self.logger.exception("Error handling signals")
        else:
            self.notify_signals(signals)
示例#6
0
    def configure(self, context):
        super().configure(context)
        self._subscriber = NioSubscriber(self._subscriber_handler,
                                         topic=self.topic())

        try:
            self._subscriber.open(on_connected=self.conn_on_connected,
                                  on_disconnected=self.conn_on_disconnected)
        except TypeError as e:
            self.logger.warning(
                "Connecting to an outdated communication module")
            # try previous interface
            self._subscriber.open()
            # no need to configure connectivity if not supported
            return

        # let connectivity configure
        self.conn_configure(self._subscriber.is_connected)
    def configure(self, context):
        super().configure(context)
        topic = self.topic()
        # If a local identifier was included use it as a prefix
        if self.local_identifier():
            topic = "{}.{}".format(self.local_identifier(), topic)
        self._subscriber = NioSubscriber(self._subscriber_handler, topic=topic)

        try:
            self._subscriber.open(on_connected=self.conn_on_connected,
                                  on_disconnected=self.conn_on_disconnected)
        except TypeError as e:
            self.logger.warning(
                "Connecting to an outdated communication module")
            # try previous interface
            self._subscriber.open()
            # no need to configure connectivity if not supported
            return

        # let connectivity configure
        self.conn_configure(self._subscriber.is_connected)
示例#8
0
class Subscriber(PubSubConnectivity, GeneratorBlock):
    """ A block for subscribing to a nio communication channel.

    Functions regardless of communication module implementation.

    Properties:
        topic (str): Defines topic to subscribe to in order to receive signals.

    """
    version = VersionProperty("1.1.1")
    topic = StringProperty(title="Topic", default="")

    def __init__(self):
        super().__init__()
        self._subscriber = None

    def configure(self, context):
        super().configure(context)
        self._subscriber = NioSubscriber(self._subscriber_handler,
                                         topic=self.topic())

        try:
            self._subscriber.open(on_connected=self.conn_on_connected,
                                  on_disconnected=self.conn_on_disconnected)
        except TypeError as e:
            self.logger.warning(
                "Connecting to an outdated communication module")
            # try previous interface
            self._subscriber.open()
            # no need to configure connectivity if not supported
            return

        # let connectivity configure
        self.conn_configure(self._subscriber.is_connected)

    def stop(self):
        """ Stop the block by closing the underlying subscriber """
        self._subscriber.close()
        super().stop()

    def _subscriber_handler(self, signals):
        self.notify_signals(signals)
示例#9
0
 def configure(self, context):
     super().configure(context)
     self._subscriber = NioSubscriber(self._subscriber_handler,
                                      topic="{}.{}".format(
                                          self.local_identifier(),
                                          self.topic()))
class LocalSubscriber(PubSubConnectivity, GeneratorBlock):
    """ A block for subscribing to a local nio communication channel.

    Functions regardless of communication module implementation.

    Unlike the regular Subscriber block, the one does not need data to be json
    """
    version = VersionProperty("1.1.1")
    topic = StringProperty(title="Topic", default="")
    local_identifier = StringProperty(title='Local Identifier',
                                      default='[[INSTANCE_ID]]',
                                      advanced=True)

    def __init__(self):
        super().__init__()
        self._subscriber = None

    def configure(self, context):
        super().configure(context)
        topic = self.topic()
        # If a local identifier was included use it as a prefix
        if self.local_identifier():
            topic = "{}.{}".format(self.local_identifier(), topic)
        self._subscriber = NioSubscriber(self._subscriber_handler, topic=topic)

        try:
            self._subscriber.open(on_connected=self.conn_on_connected,
                                  on_disconnected=self.conn_on_disconnected)
        except TypeError as e:
            self.logger.warning(
                "Connecting to an outdated communication module")
            # try previous interface
            self._subscriber.open()
            # no need to configure connectivity if not supported
            return

        # let connectivity configure
        self.conn_configure(self._subscriber.is_connected)

    def stop(self):
        """ Stop the block by closing the underlying subscriber """
        self._subscriber.close()
        super().stop()

    def _subscriber_handler(self, signals):
        try:
            signals = b64decode(signals[0].signals)
            signals = pickle.loads(signals)
        except pickle.UnpicklingError:
            self.logger.exception("Unpickling based pickle error")
        except AttributeError:
            # It's possible these came from a non-local publisher
            # This would occur in service tests or if a regular publisher
            # wanted to publish to a local topic. In the non-service test
            # case this would generally indicate bad service design but we
            # don't want to explicitly prevent/forbid it
            if (signals and isinstance(signals, list)
                    and isinstance(signals[0], Signal)):
                self.notify_signals(signals)
            else:
                raise
        except TypeError:
            self.logger.exception("Unable to decode pickled signals")
        except Exception:
            self.logger.exception("Error handling signals")
        else:
            self.notify_signals(signals)
示例#11
0
 def configure(self, context):
     super().configure(context)
     self._subscriber = NIOSubscriber(self.process_signals,
                                      topic=self.topic())