class NsqPublisher(
        AbstractPublisher, ):
    """
    使用nsq作为中间件
    """

    # noinspection PyAttributeOutsideInit
    def custom_init(self):
        self._nsqd_cleint = NsqdHTTPClient(frame_config.NSQD_HTTP_CLIENT_HOST,
                                           frame_config.NSQD_HTTP_CLIENT_PORT)
        self._producer = Producer(frame_config.NSQD_TCP_ADDRESSES)
        self._producer.start()

    def concrete_realization_of_publish(self, msg):
        # noinspection PyTypeChecker
        self._producer.publish(self._queue_name, msg.encode())

    def clear(self):
        try:
            self._nsqd_cleint.empty_topic(self._queue_name)
        except NSQHttpError as e:
            self.logger.exception(e)  # 不能清除一个不存在的topoc会报错,和其他消息队列中间件不同。
        self.logger.warning(f'清除 {self._queue_name} topic中的消息成功')

    def get_message_count(self):
        return self._nsqd_cleint.stats(
            self._queue_name)['topics'][0]['message_count']

    def close(self):
        self._producer.close()
Exemple #2
0
def test_tls_publish():
    extra_params = [
        '--tls-required', 'true',
        '--https-address', '127.0.0.1:4152',
    ]
    with NsqdIntegrationServer(extra_params=extra_params) as server:
        producer = Producer(
            server.tcp_address,
            tls_options={
                'keyfile': server.tls_key,
                'certfile': server.tls_cert,
            },
            tls_v1=True,
        )
        producer.start()

        for _ in range(100):
            producer.publish('test', b'hi')

        producer.close()
        producer.join()

        conn = NsqdHTTPClient(
            server.address,
            '4152',
            connection_class=urllib3.HTTPSConnectionPool,
            cert_reqs='CERT_NONE',
        )
        stats = conn.stats()

        assert stats['topics'][0]['depth'] == 100
Exemple #3
0
def test_max_concurrency():
    server1 = NsqdIntegrationServer()
    server2 = NsqdIntegrationServer()

    with server1, server2:
        class Accounting(object):
            count = 0
            total = 100
            concurrency = 0
            error = None

        for server in (server1, server2):
            conn = NsqdHTTPClient(server.address, server.http_port)

            for _ in range(Accounting.total // 2):
                conn.publish('test', b'danger zone!')

        reader = Reader(
            topic='test',
            channel='test',
            nsqd_tcp_addresses=[
                server1.tcp_address,
                server2.tcp_address,
            ],
            max_in_flight=5,
            max_concurrency=1,
        )

        @reader.on_exception.connect
        def error_handler(reader, message, error):
            if isinstance(error, NSQSocketError):
                return
            Accounting.error = error
            reader.close()

        @reader.on_message.connect
        def handler(reader, message):
            assert message.body == b'danger zone!'
            assert Accounting.concurrency == 0

            Accounting.concurrency += 1
            gevent.sleep()
            Accounting.concurrency -= 1

            Accounting.count += 1
            if Accounting.count == Accounting.total:
                reader.close()

        reader.start()

        if Accounting.error:
            raise Accounting.error

        assert Accounting.count == Accounting.total
Exemple #4
0
def test_backoff():
    with NsqdIntegrationServer() as server:
        conn = NsqdHTTPClient(server.address, server.http_port)

        for _ in range(500):
            conn.publish('test', 'danger zone!')

        consumer = Consumer(
            topic='test',
            channel='test',
            nsqd_tcp_addresses=[server.tcp_address],
            max_in_flight=100,
            message_handler=lambda consumer, message: None
        )

        consumer.start(block=False)
        consumer._redistributed_ready_event.wait()

        conn = next(iter(consumer._connections))
        consumer._message_backoffs[conn].failure()
        consumer._message_backoffs[conn].failure()
        consumer._start_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.BACKOFF
        assert consumer.total_ready_count == 0

        consumer._start_throttled(conn)
        consumer._redistribute_ready_state()
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.THROTTLED
        assert consumer.total_ready_count == 1

        consumer._message_backoffs[conn].success()
        consumer._complete_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.BACKOFF
        assert consumer.total_ready_count == 0

        consumer._start_throttled(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.THROTTLED
        assert consumer.total_ready_count == 1

        consumer._message_backoffs[conn].success()
        consumer._complete_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.RUNNING
        assert consumer.total_ready_count == 100
Exemple #5
0
def test_backoff():
    with NsqdIntegrationServer() as server:
        conn = NsqdHTTPClient(server.address, server.http_port)

        for _ in range(500):
            conn.publish('test', 'danger zone!')

        consumer = Consumer(topic='test',
                            channel='test',
                            nsqd_tcp_addresses=[server.tcp_address],
                            max_in_flight=100,
                            message_handler=lambda consumer, message: None)

        consumer.start(block=False)
        consumer._redistributed_ready_event.wait()

        conn = next(iter(consumer._connections))
        consumer._message_backoffs[conn].failure()
        consumer._message_backoffs[conn].failure()
        consumer._start_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.BACKOFF
        assert consumer.total_ready_count == 0

        consumer._start_throttled(conn)
        consumer._redistribute_ready_state()
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.THROTTLED
        assert consumer.total_ready_count == 1

        consumer._message_backoffs[conn].success()
        consumer._complete_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.BACKOFF
        assert consumer.total_ready_count == 0

        consumer._start_throttled(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.THROTTLED
        assert consumer.total_ready_count == 1

        consumer._message_backoffs[conn].success()
        consumer._complete_backoff(conn)
        consumer._redistribute_ready_state()

        assert consumer._connections[conn] == states.RUNNING
        assert consumer.total_ready_count == 100
Exemple #6
0
def test_multipublish():
    with NsqdIntegrationServer() as server:
        producer = Producer(server.tcp_address)
        producer.start()

        for _ in range(10):
            producer.multipublish('test', 10 * [b'hi'])

        producer.close()
        producer.join()

        conn = NsqdHTTPClient(server.address, server.http_port)
        stats = conn.stats()

        assert stats['topics'][0]['depth'] == 100
Exemple #7
0
def test_multipublish():
    with NsqdIntegrationServer() as server:
        producer = Producer(server.tcp_address)
        producer.start()

        for _ in range(10):
            producer.multipublish('test', 10 * [b'hi'])

        producer.close()
        producer.join()

        conn = NsqdHTTPClient(server.address, server.http_port)
        stats = conn.stats()

        assert stats['topics'][0]['depth'] == 100
Exemple #8
0
def test_lookupd():
    with LookupdIntegrationServer() as lookupd_server:
        server1 = NsqdIntegrationServer(lookupd=lookupd_server.tcp_address)
        server2 = NsqdIntegrationServer(lookupd=lookupd_server.tcp_address)

        with server1, server2:

            class Accounting(object):
                count = 0
                total = 500
                concurrency = 0
                error = None

            for server in (server1, server2):
                conn = NsqdHTTPClient(server.address, server.http_port)

                for _ in range(Accounting.total // 2):
                    conn.publish('test', b'danger zone!')

            consumer = Consumer(
                topic='test',
                channel='test',
                lookupd_http_addresses=lookupd_server.http_address,
                max_in_flight=32,
            )

            @consumer.on_exception.connect
            def error_handler(consumer, message, error):
                if isinstance(error, NSQSocketError):
                    return
                Accounting.error = error
                consumer.close()

            @consumer.on_message.connect
            def handler(consumer, message):
                assert message.body == b'danger zone!'

                Accounting.count += 1
                if Accounting.count == Accounting.total:
                    consumer.close()

            gevent.sleep(0.1)
            consumer.start()

            if Accounting.error:
                raise Accounting.error

            assert Accounting.count == Accounting.total
Exemple #9
0
def test_lookupd():
    with LookupdIntegrationServer() as lookupd_server:
        server1 = NsqdIntegrationServer(lookupd=lookupd_server.tcp_address)
        server2 = NsqdIntegrationServer(lookupd=lookupd_server.tcp_address)

        with server1, server2:
            class Accounting(object):
                count = 0
                total = 500
                concurrency = 0
                error = None

            for server in (server1, server2):
                conn = NsqdHTTPClient(server.address, server.http_port)

                for _ in range(Accounting.total // 2):
                    conn.publish('test', b'danger zone!')

            consumer = Consumer(
                topic='test',
                channel='test',
                lookupd_http_addresses=lookupd_server.http_address,
                max_in_flight=32,
            )

            @consumer.on_exception.connect
            def error_handler(consumer, message, error):
                if isinstance(error, NSQSocketError):
                    return
                Accounting.error = error
                consumer.close()

            @consumer.on_message.connect
            def handler(consumer, message):
                assert message.body == b'danger zone!'

                Accounting.count += 1
                if Accounting.count == Accounting.total:
                    consumer.close()

            gevent.sleep(0.1)
            consumer.start()

            if Accounting.error:
                raise Accounting.error

            assert Accounting.count == Accounting.total
Exemple #10
0
def test_async_publish():
    with NsqdIntegrationServer() as server:
        results = []
        producer = Producer(server.tcp_address)
        producer.start()

        for _ in range(100):
            results.append(producer.publish('test', b'hi', raise_error=False))

        gevent.joinall(results, raise_error=True)
        producer.close()
        producer.join()

        conn = NsqdHTTPClient(server.address, server.http_port)
        stats = conn.stats()

        assert stats['topics'][0]['depth'] == 100
Exemple #11
0
def test_async_publish():
    with NsqdIntegrationServer() as server:
        results = []
        producer = Producer(server.tcp_address)
        producer.start()

        for _ in range(100):
            results.append(producer.publish('test', b'hi', raise_error=False))

        gevent.joinall(results, raise_error=True)
        producer.close()
        producer.join()

        conn = NsqdHTTPClient(server.address, server.http_port)
        stats = conn.stats()

        assert stats['topics'][0]['depth'] == 100
Exemple #12
0
def test_messages():
    with NsqdIntegrationServer() as server:

        class Accounting(object):
            count = 0
            total = 500
            error = None

        conn = NsqdHTTPClient(server.address, server.http_port)
        for _ in range(Accounting.total):
            conn.publish('test', b'danger zone!')

        consumer = Consumer(
            topic='test',
            channel='test',
            nsqd_tcp_addresses=[server.tcp_address],
            max_in_flight=100,
        )

        @consumer.on_exception.connect
        def error_handler(consumer, message, error):
            if isinstance(error, NSQSocketError):
                return
            Accounting.error = error
            consumer.close()

        @consumer.on_message.connect
        def handler(consumer, message):
            assert message.body == b'danger zone!'

            Accounting.count += 1
            if Accounting.count == Accounting.total:
                consumer.close()

        consumer.start()

        if Accounting.error:
            raise Accounting.error

        assert Accounting.count == Accounting.total
Exemple #13
0
def test_messages():
    with NsqdIntegrationServer() as server:

        class Accounting(object):
            count = 0
            total = 500
            error = None

        conn = NsqdHTTPClient(server.address, server.http_port)
        for _ in range(Accounting.total):
            conn.publish('test', b'danger zone!')

        consumer = Consumer(
            topic='test',
            channel='test',
            nsqd_tcp_addresses=[server.tcp_address],
            max_in_flight=100,
        )

        @consumer.on_exception.connect
        def error_handler(consumer, message, error):
            if isinstance(error, NSQSocketError):
                return
            Accounting.error = error
            consumer.close()

        @consumer.on_message.connect
        def handler(consumer, message):
            assert message.body == b'danger zone!'

            Accounting.count += 1
            if Accounting.count == Accounting.total:
                consumer.close()

        consumer.start()

        if Accounting.error:
            raise Accounting.error

        assert Accounting.count == Accounting.total
 def custom_init(self):
     self._nsqd_cleint = NsqdHTTPClient(frame_config.NSQD_HTTP_CLIENT_HOST,
                                        frame_config.NSQD_HTTP_CLIENT_PORT)
     self._producer = Producer(frame_config.NSQD_TCP_ADDRESSES)
     self._producer.start()