def _thread_loop(self, context, pipe): # Pyre helper functions def setup_group_member(): group_member = Pyre(self.name) # set headers for header in self.default_headers: group_member.set_header(*header) # join active group group_member.join(self.active_group) # start group_member group_member.start() return group_member def shutdown_group_member(node): node.leave(self.active_group) node.stop() # setup sockets local_in = Msg_Receiver(context, self.g_pool.ipc_sub_url, topics=("remote_notify.", )) local_out = Msg_Dispatcher(context, self.g_pool.ipc_push_url) group_member = setup_group_member() # register sockets for polling poller = zmq.Poller() poller.register(pipe, zmq.POLLIN) poller.register(local_in.socket, zmq.POLLIN) poller.register(group_member.socket(), zmq.POLLIN) logger.info("Pupil Groups started.") # Poll loop while True: # Wait for next readable item readable = dict(poller.poll()) # shout or whisper marked notifications if local_in.socket in readable: topic, notification = local_in.recv() remote_key = "remote_notify" if notification[remote_key] == "all": del notification[remote_key] serialized = serializer.dumps(notification) group_member.shout(self.active_group, serialized) else: peer_uuid_bytes = notification[remote_key] del notification[remote_key] serialized = serializer.dumps(notification) peer_uuid = uuid.UUID(bytes=peer_uuid_bytes) group_member.whisper(peer_uuid, serialized) if group_member.socket() in readable: event = PyreEvent(group_member) if event.msg: for msg in event.msg: try: # try to unpack data notification = serializer.loads(msg, encoding="utf-8") # test if dictionary and if `subject` key is present notification["subject"] # add peer information notification["groups.peer"] = { "uuid_bytes": event.peer_uuid_bytes, "name": event.peer_name, "arrival_timestamp": self.g_pool.get_timestamp(), "type": event.type, } local_out.notify(notification) except Exception: logger.info( "Dropped garbage data by peer {} ({})".format( event.peer_name, event.peer_uuid)) elif event.type == "JOIN" and event.group == self.active_group: local_out.notify({ "subject": "groups.member_joined", "name": event.peer_name, "uuid_bytes": event.peer_uuid_bytes, }) elif (event.type == "LEAVE" and event.group == self.active_group) or event.type == "EXIT": local_out.notify({ "subject": "groups.member_left", "name": event.peer_name, "uuid_bytes": event.peer_uuid_bytes, }) if pipe in readable: command = pipe.recv_string() if command == "$RESTART": # Restart group_member node to change name poller.unregister(group_member.socket()) shutdown_group_member(group_member) group_member = setup_group_member() poller.register(group_member.socket(), zmq.POLLIN) elif command == "$TERM": break del local_in del local_out shutdown_group_member(group_member) self.thread_pipe = None
def _thread_loop(self,context,pipe): # Pyre helper functions def setup_group_member(): group_member = Pyre(self.name) # set headers for header in self.default_headers: group_member.set_header(*header) # join active group group_member.join(self.active_group) # start group_member group_member.start() return group_member def shutdown_group_member(node): node.leave(self.active_group) node.stop() # setup sockets local_in = Msg_Receiver(context, self.g_pool.ipc_sub_url, topics=('remote_notify.',)) local_out = Msg_Dispatcher(context, self.g_pool.ipc_push_url) group_member = setup_group_member() # register sockets for polling poller = zmq.Poller() poller.register(pipe,zmq.POLLIN) poller.register(local_in.socket,zmq.POLLIN) poller.register(group_member.socket(),zmq.POLLIN) logger.info('Pupil Groups started.') # Poll loop while True: # Wait for next readable item readable = dict(poller.poll()) # shout or whisper marked notifications if local_in.socket in readable: topic, notification = local_in.recv() remote_key = 'remote_notify' if notification[remote_key] == 'all': del notification[remote_key] serialized = serializer.dumps(notification) group_member.shout(self.active_group,serialized) else: peer_uuid_bytes = notification[remote_key] del notification[remote_key] serialized = serializer.dumps(notification) peer_uuid = uuid.UUID(bytes=peer_uuid_bytes) group_member.whisper(peer_uuid,serialized) if group_member.socket() in readable: event = PyreEvent(group_member) if event.msg: for msg in event.msg: try: # try to unpack data notification = serializer.loads(msg) # test if dictionary and if `subject` key is present notification['subject'] # add peer information notification['groups.peer'] = { 'uuid_bytes': event.peer_uuid_bytes, 'name': event.peer_name, 'arrival_timestamp': self.g_pool.get_timestamp(), 'type': event.type } local_out.notify(notification) except Exception as e: logger.info('Dropped garbage data by peer %s (%s)'%(event.peer_name, event.peer_uuid)) elif event.type == 'JOIN' and event.group == self.active_group: local_out.notify({ 'subject': 'groups.member_joined', 'name': event.peer_name, 'uuid_bytes': event.peer_uuid_bytes }) elif (event.type == 'LEAVE' and \ event.group == self.active_group) or \ event.type == 'EXIT': local_out.notify({ 'subject': 'groups.member_left', 'name': event.peer_name, 'uuid_bytes': event.peer_uuid_bytes }) if pipe in readable: command = pipe.recv() if command == '$RESTART': # Restart group_member node to change name poller.unregister(group_member.socket()) shutdown_group_member(group_member) group_member = setup_group_member() poller.register(group_member.socket(),zmq.POLLIN) elif command == '$TERM': break del local_in del local_out shutdown_group_member(group_member) self.thread_pipe = None