예제 #1
0
class QueueKafka(QueueBase.QueueBase):
    @QueueBase.catch
    def __init__(self, name, host='web14', port=51092, **kwargs):
        QueueBase.QueueBase.__init__(self, name, host, port)
        self.__queue = []
        self.__kafka = KafkaClient('%s:%d' % (host, port))
        self.__producer = SimpleProducer(self.__kafka, async=kwargs.get('async', False))
        self.__producer.client.ensure_topic_exists(self.name)
        self.__consumer = SimpleConsumer(self.__kafka, self.name + '_consumer', self.name, auto_commit_every_n=1)

    def __del__(self):
        if self.__kafka:
            [self.put(x.message.value) for x in self.__queue]
            self.__kafka.close()

    @QueueBase.catch
    def put(self, value, *args, **kwargs):
        if isinstance(value, dict) or isinstance(value, list):
            self.__producer.send_messages(self.name, json.dumps(value))
        else:
            self.__producer.send_messages(self.name, value.encode('utf-8') if isinstance(value, unicode) else value)

    @QueueBase.catch
    def get(self, *args, **kwargs):
        if not self.__queue:
            self.__consumer._fetch()
            kq = self.__consumer.queue
            while not kq.empty():
                partition, result = kq.get_nowait()
                self.__queue.append(result)
                self.__consumer.offsets[partition] += 1
                self.__consumer.count_since_commit += 1
            self.__consumer.queue = Queue()
            self.__consumer.commit()
        return self.__queue.pop().message.value if self.__queue else None

    @QueueBase.catch
    def size(self, *args, **kwargs):
        count = 0
        for k, v in self.__consumer.offsets.items():
            reqs = [common.OffsetRequest(self.name, k, -1, 1)]
            (resp, ) = self.__consumer.client.send_offset_request(reqs)
            count += (resp.offsets[0] - v)
        return count + len(self.__queue)
예제 #2
0
class kafka:
    def __init__(self, host, port, table_name, **args):
        """
        :param host
        :param port
        :param table_name
        :return: kafka
        """
        self.queue = []
        self.queue_name = table_name.replace(":", "_")
        # self.kafka = KafkaClient('%s:%d' % (host, port))
        self.kafka = KafkaClient(hosts=host, client_id=self.queue_name)
        self.producer = SimpleProducer(
            self.kafka,
            async=args['async'] if args.has_key('async') else False)
        self.producer.client.ensure_topic_exists(self.queue_name)
        self.consumer = SimpleConsumer(self.kafka,
                                       self.queue_name + "_consumer",
                                       self.queue_name,
                                       auto_commit_every_n=1,
                                       max_buffer_size=None)

        print 'success init kafka connection'

    def __del__(self):
        if self.kafka:
            [self.save(x.message.value) for x in self.queue]
            self.kafka.close()

    def save(self, data, **args):
        try:
            if isinstance(data, dict) or isinstance(data, list):
                self.producer.send_messages(self.queue_name, json.dumps(data))
            elif isinstance(data, unicode):
                self.producer.send_messages(self.queue_name,
                                            data.encode('utf-8'))
            else:
                self.producer.send_messages(self.queue_name, data)
        except Exception as e:
            print e
            time.sleep(60)

    def get(self, **args):
        #         self.consumer.seek(369600, 0)
        if not self.queue:
            try:
                self.consumer._fetch()
            except Exception as e:
                print e
            kq = self.consumer.queue
            while not kq.empty():
                partition, result = kq.get_nowait()
                self.queue.append(result)
                self.consumer.offsets[partition] += 1
                self.consumer.count_since_commit += 1

            self.consumer.queue = Queue()
            self.consumer.commit()

        if self.queue:
            return self.queue.pop().message.value
        else:
            return None

    def size(self, **args):
        count = 0
        for k, v in self.consumer.offsets.items():
            reqs = [common.OffsetRequest(self.queue_name, k, -1, 1)]
            (resp, ) = self.consumer.client.send_offset_request(reqs)
            count += (resp.offsets[0] - v)
        return count + len(self.queue)

    # 切换队列
    def select_queue(self, name):
        self.queue_name = name.replace(":", "_")
        self.consumer = SimpleConsumer(self.kafka,
                                       self.queue_name + "_consumer",
                                       self.queue_name,
                                       max_buffer_size=None)