예제 #1
0
    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
예제 #2
0
    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