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
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
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