Ejemplo n.º 1
0
    def recv_message(self, *args, **kwargs):
        r"""Receive a message.

        Args:
            *args: Arguments are passed to the forked comm's recv_message method.
            **kwargs: Keyword arguments are passed to the forked comm's recv_message
                method.

        Returns:
            CommMessage: Received message.

        """
        timeout = kwargs.pop('timeout', None)
        if timeout is None:
            timeout = self.recv_timeout
        kwargs['timeout'] = 0
        first_comm = True
        T = self.start_timeout(timeout, key_suffix='recv:forkd')
        out = None
        i = 0
        while ((not T.is_out) or first_comm) and self.is_open and (out is None):
            for i in range(len(self)):
                if out is not None:
                    break
                x = self.curr_comm
                if x.is_open:
                    msg = x.recv_message(*args, **kwargs)
                    self.errors += x.errors
                    if msg.flag == CommBase.FLAG_EOF:
                        self.eof_recv[self.curr_comm_index % len(self)] = 1
                        if sum(self.eof_recv) == len(self):
                            out = msg
                        else:
                            x.finalize_message(msg)
                    elif msg.flag not in [CommBase.FLAG_FAILURE, CommBase.FLAG_EMPTY]:
                        out = msg
                self.curr_comm_index += 1
            first_comm = False
            if out is None:
                self.sleep()
        self.stop_timeout(key_suffix='recv:forkd')
        if out is None:
            if self.is_closed:
                self.debug('Comm closed')
                out = CommBase.CommMessage(flag=CommBase.FLAG_FAILURE)
            else:
                out = CommBase.CommMessage(flag=CommBase.FLAG_EMPTY,
                                           args=self.last_comm.empty_obj_recv)
        out.args = {i: out.args}
        return out
Ejemplo n.º 2
0
    def remove_model(self, direction, name):
        r"""Remove a model from the list of models.

        Args:
            direction (str): Direction of model.
            name (str): Name of model exiting.

        Returns:
            bool: True if all of the input/output models have signed
                off; False otherwise.

        """
        with self.lock:
            if (direction == "input") and (name in self.clients):
                super(RPCRequestDriver, self).send_message(
                    CommBase.CommMessage(args=YGG_CLIENT_EOF,
                                         flag=CommBase.FLAG_SUCCESS),
                    header_kwargs={
                        'raw': True,
                        'model': name
                    },
                    skip_processing=True)
            out = super(RPCRequestDriver, self).remove_model(direction, name)
            if out:
                self.send_eof()
            return out
Ejemplo n.º 3
0
 def test_send_recv_closed(self, instance, send_comm, recv_comm, test_msg):
     r"""Test sending/receiving with queues closed."""
     instance.close_comm()
     send_comm.close()
     recv_comm.close()
     assert (instance.is_comm_closed)
     assert (send_comm.is_closed)
     assert (recv_comm.is_closed)
     flag = instance.send_message(CommBase.CommMessage(args=test_msg))
     assert (not flag)
     flag = instance.recv_message()
     if instance.icomm._commtype != 'value':
         assert (not flag)
     # Short
     if instance.icomm._commtype != 'value':
         flag = send_comm.send(test_msg)
         assert (not flag)
     flag, ret = recv_comm.recv()
     if instance.icomm._commtype != 'value':
         assert (not flag)
         assert (ret is None)
     # Long
     if instance.icomm._commtype != 'value':
         flag = send_comm.send_nolimit(test_msg)
         assert (not flag)
     flag, ret = recv_comm.recv_nolimit()
     if instance.icomm._commtype != 'value':
         assert (not flag)
         assert (ret is None)
     instance.confirm_output(timeout=1.0)
Ejemplo n.º 4
0
 def test_send_recv(self):
     r"""Test sending/receiving with queues closed."""
     self.instance.close_comm()
     self.send_comm.close()
     self.recv_comm.close()
     assert (self.instance.is_comm_closed)
     assert (self.send_comm.is_closed)
     assert (self.recv_comm.is_closed)
     flag = self.instance.send_message(
         CommBase.CommMessage(args=self.test_msg))
     assert (not flag)
     flag = self.instance.recv_message()
     if self.instance.icomm._commtype != 'value':
         assert (not flag)
     # Short
     if self.instance.icomm._commtype != 'value':
         flag = self.send_comm.send(self.test_msg)
         assert (not flag)
     flag, ret = self.recv_comm.recv()
     if self.instance.icomm._commtype != 'value':
         assert (not flag)
         self.assert_equal(ret, None)
     # Long
     if self.instance.icomm._commtype != 'value':
         flag = self.send_comm.send_nolimit(self.test_msg)
         assert (not flag)
     flag, ret = self.recv_comm.recv_nolimit()
     if self.instance.icomm._commtype != 'value':
         assert (not flag)
         self.assert_equal(ret, None)
     self.instance.confirm_output(timeout=1.0)
Ejemplo n.º 5
0
    def recv_message(self, timeout=None, **kwargs):
        r"""Receive a message.

        Args:
            *args: Arguments are passed to the response comm's recv_message method.
            **kwargs: Keyword arguments are passed to the response comm's recv_message
                method.

        Returns:
            CommMessage: Received message.

        """
        # Sleep until there is a message
        if timeout is None:
            timeout = kwargs.get('timeout', self.recv_timeout)
        T = self.start_timeout(timeout, key_suffix='.recv:backlog')
        while (not T.is_out) and (not self.backlog_ready.is_set()):
            self.backlog_ready.wait(self.sleeptime)
        self.stop_timeout(key_suffix='.recv:backlog')
        # Handle absence of messages
        if self.n_msg_backlog == 0:
            self.verbose_debug("No messages waiting.")
            if self.is_closed:
                self.debug(("No messages waiting and comm closed."
                            "%s, %s, %s")
                           % (self.backlog_thread is not None,
                              not self.backlog_thread.was_break,
                              self.backlog_thread.is_alive()))
                self.printStatus(level='debug')
                if self.backlog_thread.was_break:
                    self.debug("Break stack:\n%s",
                               self.backlog_thread.break_stack)
                out = CommBase.CommMessage(flag=CommBase.FLAG_FAILURE)
            else:
                out = CommBase.CommMessage(flag=CommBase.FLAG_EMPTY,
                                           args=self.empty_obj_recv)
        # Return backlogged message
        else:
            self.debug('Returning backlogged received message')
            out = self.pop_backlog()
        return out
Ejemplo n.º 6
0
    def send_eof(self, **kwargs):
        r"""Send EOF message.

        Returns:
            bool: Success or failure of send.

        """
        with self.lock:
            if self._eof_sent:  # pragma: debug
                self.debug('Already sent EOF')
                return False
            self._eof_sent = True
        self.debug('Sent EOF')
        msg = CommBase.CommMessage(flag=CommBase.FLAG_EOF,
                                   args=self.ocomm.eof_msg)
        return self.send_message(msg, **kwargs)
Ejemplo n.º 7
0
    def on_eof(self, msg):
        r"""On EOF, decrement number of clients. Only send EOF if the number
        of clients drops to 0.

        Args:
            msg (CommMessage): Message object that provided the EOF.

        Returns:
            CommMessage, bool: Value that should be returned by recv_message on EOF.

        """
        with self.lock:
            self.remove_model('input', msg.header.get('model', ''))
            if self.nclients == 0:
                self.debug("All clients have signed off (EOF).")
                return super(RPCRequestDriver, self).on_eof(msg)
        return CommBase.CommMessage(flag=CommBase.FLAG_EMPTY,
                                    args=self.icomm.empty_obj_recv)
Ejemplo n.º 8
0
    def recv(self,
             timeout=None,
             return_message_object=False,
             dont_finalize=False,
             **kwargs):
        r"""Receive a message.

        Args:
            *args: All arguments are passed to comm _recv method.
            return_message_object (bool, optional): If True, the full wrapped
                CommMessage message object is returned instead of the tuple.
                Defaults to False.
            dont_finalize (bool, optional): If True, finalize_message will not
                be called even if async_recv_method is 'recv_message'. Defaults
                to False.
            **kwargs: All keywords arguments are passed to comm _recv method.

        Returns:
            tuple (bool, obj): Success or failure of receive and received
                message.

        """
        self.precheck('recv')
        # Sleep until there is a message
        if timeout is None:
            timeout = kwargs.get('timeout', self.recv_timeout)
        T = self.start_timeout(timeout, key_suffix='.recv:backlog')
        while (not T.is_out) and (not self.backlog_ready.is_set()):
            self.backlog_ready.wait(self.sleeptime)
        self.stop_timeout(key_suffix='.recv:backlog')
        # Handle absence of messages
        if self.n_msg_backlog == 0:
            self.verbose_debug("No messages waiting.")
            if self.is_closed:
                self.info(("No messages waiting and comm closed."
                           "%s, %s, %s") % (self.backlog_thread is not None,
                                            not self.backlog_thread.was_break,
                                            self.backlog_thread.is_alive()))
                self.printStatus()
                if self.backlog_thread.was_break:
                    self.info("Break stack:\n%s",
                              self.backlog_thread.break_stack)
                out = CommBase.CommMessage(flag=CommBase.FLAG_FAILURE)
            else:
                out = CommBase.CommMessage(flag=CommBase.FLAG_EMPTY,
                                           args=self.empty_obj_recv)
        # Return backlogged message
        else:
            self.debug('Returning backlogged received message')
            out = self.pop_backlog()
            if not dont_finalize:
                # if self.is_eof(out.args) and self.close_on_eof_recv:
                if (out.flag == CommBase.FLAG_EOF) and self.close_on_eof_recv:
                    self.close()
                    out.flag = CommBase.FLAG_FAILURE
                self._used = True
        if not dont_finalize:
            kws_finalize = {
                k: kwargs.pop(k)
                for k in self._finalize_message_kws if k in kwargs
            }
            if self.async_recv_method != 'recv_message':
                out.finalized = False
                kws_finalize['skip_processing'] = True
            out = self._wrapped.finalize_message(out, **kws_finalize)
        if not return_message_object:
            out = (bool(out.flag), out.args)
        return out
Ejemplo n.º 9
0
    def recv_message(self, *args, **kwargs):
        r"""Receive a message.

        Args:
            *args: Arguments are passed to the forked comm's recv_message method.
            **kwargs: Keyword arguments are passed to the forked comm's recv_message
                method.

        Returns:
            CommMessage: Received message.

        """
        timeout = kwargs.pop('timeout', None)
        if timeout is None:
            timeout = self.recv_timeout
        kwargs['timeout'] = 0
        first_comm = True
        T = self.start_timeout(timeout, key_suffix='recv:forkd')
        out = None
        out_gather = {}
        idx = None

        if self.pattern == 'gather':

            def complete():
                return (len(out_gather) == len(self))
        else:

            def complete():
                return bool(out_gather)

        while ((not T.is_out)
               or first_comm) and self.is_open and (not complete()):
            for i in range(len(self)):
                if complete():
                    break
                idx = self.curr_comm_index % len(self)
                x = self.curr_comm
                if idx not in out_gather:
                    if self.comm_list_backlog[idx]:
                        out_gather[idx] = self.comm_list_backlog[idx].pop(0)
                    elif x.is_open:
                        msg = x.recv_message(*args, **kwargs)
                        self.errors += x.errors
                        if msg.flag == CommBase.FLAG_EOF:
                            self.eof_recv[idx] = 1
                            if self.pattern == 'gather':
                                assert (all((v.flag == CommBase.FLAG_EOF)
                                            for v in out_gather.values()))
                                out_gather[idx] = msg
                            elif sum(self.eof_recv) == len(self):
                                out_gather[idx] = msg
                            else:
                                x.finalize_message(msg)
                        elif msg.flag == CommBase.FLAG_SUCCESS:
                            out_gather[idx] = msg
                self.curr_comm_index += 1
            first_comm = False
            if not complete():
                self.sleep()
        self.stop_timeout(key_suffix='recv:forkd')
        if complete():
            if self.pattern == 'cycle':
                idx, out = next(iter(out_gather.items()))
                args_copy = copy.deepcopy(out)
                out.args = {idx: args_copy}
            elif self.pattern == 'gather':
                out = copy.deepcopy(next(iter(out_gather.values())))
                out.args = {idx: v for idx, v in out_gather.items()}
                # TODO: Gather header/type etc?
        else:
            for idx, v in out_gather.items():
                self.comm_list_backlog[idx].append(v)
            if self.is_closed:
                self.debug('Comm closed')
                out = CommBase.CommMessage(flag=CommBase.FLAG_FAILURE)
            else:
                out = CommBase.CommMessage(flag=CommBase.FLAG_EMPTY)
                if self.pattern == 'cycle':
                    out.args = self.last_comm.empty_obj_recv
                else:
                    out.args = []
        return out