예제 #1
0
 def recv(self):
     # poll the zmq socket, populate the recv queue deque with responses
     events = zmq.zmq_poll([(self.sock, zmq.POLLIN)], 50)
     if not events:
         return None, None, None
     slaveid, _, event_json = self.sock.recv_multipart(flags=zmq.NOBLOCK)
     event_data = json.loads(event_json)
     event_name = event_data.pop('_event_name')
     if slaveid not in self.slaves:  # its byte-string coming from recv
         self.log.error("message from terminated worker %s %s %s", slaveid,
                        event_name, event_data)
         return None, None, None
     return self.slaves[slaveid], event_data, event_name
예제 #2
0
    def recv(self):
        # poll the zmq socket, populate the recv queue deque with responses

        events = zmq.zmq_poll([(self.sock, zmq.POLLIN)], 50)
        if not events:
            return None, None, None
        slaveid, _, event_json = self.sock.recv_multipart(flags=zmq.NOBLOCK)
        event_data = json.loads(event_json)
        event_name = event_data.pop('_event_name')
        if slaveid not in self.slaves:
            self.log.error("message from terminated worker %s %s %s",
                           slaveid, event_name, event_data)
            return None, None, None
        return self.slaves[slaveid], event_data, event_name
예제 #3
0
    def poll(self, timeout=None, flags=POLLIN):
        """poll the socket for events
        
        The default is to poll forever for incoming
        events.  Timeout is in milliseconds, if specified.

        Parameters
        ----------
        timeout : int [default: None]
            The timeout (in milliseconds) to wait for an event. If unspecified
            (or specified None), will wait forever for an event.
        flags : bitfield (int) [default: POLLIN]
            The event flags to poll for (any combination of POLLIN|POLLOUT).
            The default is to check for incoming events (POLLIN).

        Returns
        -------
        events : bitfield (int)
            The events that are ready and waiting.  Will be 0 if no events were ready
            by the time timeout was reached.
        """

        if self.closed:
            raise ZMQError(ENOTSUP)

        poller_class = self._poller_class
        if poller_class is not None:
            p = self._poller_class()
            p.register(self, flags)
            evts = dict(p.poll(timeout))
        else:
            if timeout is None or timeout < 0:
                timeout = -1
            elif isinstance(timeout, float):
                timeout = int(timeout)
            evts = dict(zmq.zmq_poll([(self,flags)], timeout))
        # return 0 if no events, otherwise return event bitfield
        return evts.get(self, 0)
    def __traffic(self):
        """Thread responsible for retrieving packets from trex server and send them to the workers and the other way around."""
        try:
            self.logger.info("traffic started")
            sockets = {}
            for c in self.workers_connections:
                sockets[c.fileno()] = c

            # Create list of socket to listen to
            nb_fds = len(self.workers_connections) + 1
            polling_items = (zmq.zmq_pollitem_t * nb_fds)()

            for i in range(len(self.workers_connections)):
                polling_items[i].socket = 0
                polling_items[i].fd = self.workers_connections[i].fileno()
                polling_items[i].events = zmq.POLLIN
                polling_items[i].revents = 0

            polling_items[len(
                self.workers_connections)].socket = self.zmq_socket.handle
            polling_items[len(self.workers_connections)].fd = 0
            polling_items[len(self.workers_connections)].events = zmq.POLLIN
            polling_items[len(self.workers_connections)].revents = 0

            timeout = -1
            while not self.is_stopped.is_set():
                ret = zmq.zmq_poll(polling_items, ctypes.c_int(nb_fds),
                                   ctypes.c_long(timeout))
                if ret == -1:
                    # Error
                    self.logger.error("Error in ZMQ select, returned %d", ret)
                    break
                elif ret > 0:
                    # Some events occured
                    for l in polling_items:
                        if (l.revents & zmq.POLLIN) == 0:
                            continue
                        if l.socket == self.zmq_socket.handle:
                            rx_bytes = self.zmq_socket.recv()
                            dst_mac = rx_bytes[:6]

                            # packet switching
                            with self.mac_routes_lock:
                                pkt_connection_id = self.pkt_connection_id_by_mac.get(
                                    dst_mac, None)

                                if pkt_connection_id is not None:
                                    self.logger.debug(
                                        "forwarded packet to worker: mac: {}".
                                        format(dst_mac))
                                    self.workers_connections[
                                        pkt_connection_id].send(rx_bytes)

                                elif dst_mac == b'\xff\xff\xff\xff\xff\xff':
                                    # send to all workers
                                    self.logger.debug(
                                        "received broadcast frame, forwarding to all workers"
                                    )
                                    for pipe_id in self.pkt_connection_id_by_mac.values(
                                    ):

                                        self.workers_connections[pipe_id].send(
                                            rx_bytes)

                                else:
                                    self.logger.debug(
                                        "dropped packet: unknown mac: {}".
                                        format(dst_mac))
                        elif l.fd:
                            sock = sockets[l.fd]
                            while sock.poll():
                                pkt = sock.recv()
                                self.zmq_socket.send(pkt)

            self.logger.info("traffic stopped")
        except EOFError:
            # stop
            return
        except zmq.error.ContextTerminated as e:
            # FIXME happens at the end
            self.logger.warn("traffic stopped due to ZMQ error: {}".format(e))
            self.stop()
        except zmq.error.ZMQError as e:
            if self.is_stopped.is_set():
                # Stop
                return
            self.logger.warn("traffic stopped due to ZMQ error: {}".format(e))
            self.stop()
        except TRexError as e:
            self.logger.warn("down_up stopped due to TRexError")
            self.stop()
        except Exception as e:
            self.logger.exception("Unexpected exception")
            try:
                report = RPCExceptionReport(e)
                with self.manager_cmd_connection_lock:
                    self.manager_cmd_connection.send(report)
            except ConnectionError:
                return