async def test_reclaim_pending_messages(loop, redis_client, redis_pool,
                                        dummy_api):
    """Test that unacked messages belonging to this consumer get reclaimed on startup
    """

    # Add a message
    await redis_client.xadd(
        "my.dummy.my_event:stream",
        fields={
            b"api_name": b"my.dummy",
            b"event_name": b"my_event",
            b"id": b"123",
            b"version": b"1",
            b":field": b'"value"',
        },
    )
    # Create the consumer group
    await redis_client.xgroup_create("my.dummy.my_event:stream",
                                     "test_group",
                                     latest_id="0")

    # Claim it in the name of ourselves
    await redis_client.xread_group("test_group",
                                   "good_consumer",
                                   ["my.dummy.my_event:stream"],
                                   latest_ids=[0])

    event_transport = RedisEventTransport(
        redis_pool=redis_pool,
        consumer_group_prefix="",
        consumer_name="good_consumer",
        stream_use=StreamUse.PER_EVENT,
    )
    consumer = event_transport.consume(listen_for=[("my.dummy", "my_event")],
                                       since="0",
                                       consumer_group="test_group")

    messages = []

    async def consume():
        async for message in consumer:
            if isinstance(message, EventMessage):
                messages.append(message)

    task = asyncio.ensure_future(consume())
    await asyncio.sleep(0.1)
    await cancel(task)

    assert len(messages) == 1
    assert messages[0].api_name == "my.dummy"
    assert messages[0].event_name == "my_event"
    assert messages[0].kwargs == {"field": "value"}
    assert messages[0].native_id
    assert type(messages[0].native_id) == str

    # Now check that redis believes the message has been consumed
    total_pending, *_ = await redis_client.xpending("my.dummy.my_event:stream",
                                                    "test_group")
    assert total_pending == 0
Beispiel #2
0
async def test_reclaim_lost_messages_consume(loop, redis_client, redis_pool, dummy_api):
    """Test that messages which another consumer has timed out on can be reclaimed

    Unlike the above test, we call consume() here, not _reclaim_lost_messages()
    """

    # Add a message
    await redis_client.xadd(
        "my.dummy.my_event:stream",
        fields={
            b"api_name": b"my.dummy",
            b"event_name": b"my_event",
            b"id": b"123",
            b"version": b"1",
            b":field": b'"value"',
        },
    )
    # Create the consumer group
    await redis_client.xgroup_create(
        stream="my.dummy.my_event:stream", group_name="test_service-test_listener", latest_id="0"
    )

    # Claim it in the name of another consumer
    await redis_client.xread_group(
        group_name="test_service-test_listener",
        consumer_name="bad_consumer",
        streams=["my.dummy.my_event:stream"],
        latest_ids=[">"],
    )
    # Sleep a moment to fake a short timeout
    await asyncio.sleep(0.1)

    event_transport = RedisEventTransport(
        redis_pool=redis_pool,
        service_name="test_service",
        consumer_name="good_consumer",
        acknowledgement_timeout=0.01,  # in ms, short for the sake of testing
        stream_use=StreamUse.PER_EVENT,
    )
    consumer = event_transport.consume(
        listen_for=[("my.dummy", "my_event")],
        since="0",
        listener_name="test_listener",
        bus_client=None,
    )

    messages = []

    async def consume():
        async for messages_ in consumer:
            messages.extend(messages_)

    task = asyncio.ensure_future(consume())
    await asyncio.sleep(0.1)
    await cancel(task)

    assert len(messages) == 1
    async def co_consume(group_number):
        event_transport = RedisEventTransport(
            redis_pool=redis_pool,
            consumer_group_prefix=f"test_cg{group_number}",
            consumer_name=f"test_consumer",
            stream_use=StreamUse.PER_EVENT,
        )

        async for message_ in event_transport.consume(
            [("my.dummy", "my_event")], {}):
            messages.append(message_)
 async def co_consume(consumer_number):
     event_transport = RedisEventTransport(
         redis_pool=redis_pool,
         consumer_group_prefix="test_cg",
         consumer_name=f"test_consumer{consumer_number}",
         stream_use=StreamUse.PER_EVENT,
     )
     consumer = event_transport.consume(listen_for=[("my.dummy", "my_event")
                                                    ],
                                        consumer_group="single_group")
     async for message_ in consumer:
         messages.append(message_)
Beispiel #5
0
 async def co_consume(consumer_number):
     event_transport = RedisEventTransport(
         redis_pool=redis_pool,
         service_name="test_service",
         consumer_name=f"test_consumer{consumer_number}",
         stream_use=StreamUse.PER_EVENT,
     )
     consumer = event_transport.consume(
         listen_for=[("my.dummy", "my_event")], listener_name="test_listener", bus_client=None
     )
     async for messages in consumer:
         events.append(messages)
         await event_transport.acknowledge(*messages, bus_client=None)
Beispiel #6
0
    async def co_consume(group_number):
        event_transport = RedisEventTransport(
            redis_pool=redis_pool,
            service_name=f"test_service{group_number}",
            consumer_name=f"test_consumer",
            stream_use=StreamUse.PER_EVENT,
        )

        async for messages_ in event_transport.consume(
            [("my.dummy", "my_event")], "test_listener", bus_client=None
        ):
            messages.append(messages_)
            await event_transport.acknowledge(*messages_, bus_client=None)
Beispiel #7
0
async def test_reclaim_lost_messages(loop, redis_client, redis_pool, dummy_api):
    """Test that messages which another consumer has timed out on can be reclaimed"""

    # Add a message
    await redis_client.xadd(
        "my.dummy.my_event:stream",
        fields={
            b"api_name": b"my.dummy",
            b"event_name": b"my_event",
            b"id": b"123",
            b"version": b"1",
            b":field": b'"value"',
        },
    )
    # Create the consumer group
    await redis_client.xgroup_create(
        stream="my.dummy.my_event:stream", group_name="test_service", latest_id="0"
    )

    # Claim it in the name of another consumer
    result = await redis_client.xread_group(
        group_name="test_service",
        consumer_name="bad_consumer",
        streams=["my.dummy.my_event:stream"],
        latest_ids=[">"],
    )
    assert result, "Didn't actually manage to claim any message"

    # Sleep a moment to fake a short timeout
    await asyncio.sleep(0.1)

    event_transport = RedisEventTransport(
        redis_pool=redis_pool,
        service_name="test_service",
        consumer_name="good_consumer",
        acknowledgement_timeout=0.01,  # in ms, short for the sake of testing
        stream_use=StreamUse.PER_EVENT,
    )
    reclaimer = event_transport._reclaim_lost_messages(
        stream_names=["my.dummy.my_event:stream"],
        consumer_group="test_service",
        expected_events={"my_event"},
    )

    reclaimed_messages = []
    async for m in reclaimer:
        reclaimed_messages.extend(m)

    assert len(reclaimed_messages) == 1
    assert reclaimed_messages[0].native_id
    assert type(reclaimed_messages[0].native_id) == str
Beispiel #8
0
async def test_reclaim_lost_messages_ignores_non_timed_out_messages(
    loop, redis_client, redis_pool, dummy_api
):
    """Ensure messages which have not timed out are not reclaimed"""

    # Add a message
    await redis_client.xadd(
        "my.dummy.my_event:stream",
        fields={
            b"api_name": b"my.dummy",
            b"event_name": b"my_event",
            b"id": b"123",
            b":field": b'"value"',
        },
    )
    # Create the consumer group
    await redis_client.xgroup_create(
        stream="my.dummy.my_event:stream", group_name="test_service", latest_id="0"
    )

    # Claim it in the name of another consumer
    await redis_client.xread_group(
        group_name="test_service",
        consumer_name="bad_consumer",
        streams=["my.dummy.my_event:stream"],
        latest_ids=[">"],
    )
    # Sleep a moment to fake a short timeout
    await asyncio.sleep(0.1)

    event_transport = RedisEventTransport(
        redis_pool=redis_pool,
        service_name="test_service",
        consumer_name="good_consumer",
        # in ms, longer as we want to check that the messages is not reclaimed
        acknowledgement_timeout=0.9,
        stream_use=StreamUse.PER_EVENT,
    )
    reclaimer = event_transport._reclaim_lost_messages(
        stream_names=["my.dummy.my_event:stream"],
        consumer_group="test_service",
        expected_events={"my_event"},
    )
    reclaimed_messages = [m async for m in reclaimer]
    assert len(reclaimed_messages) == 0
async def test_reclaim_lost_messages(loop, redis_client, redis_pool,
                                     dummy_api):
    """Test that messages which another consumer has timed out on can be reclaimed"""

    # Add a message
    await redis_client.xadd(
        "my.dummy.my_event:stream",
        fields={
            b"api_name": b"my.dummy",
            b"event_name": b"my_event",
            b"id": b"123",
            b"version": b"1",
            b":field": b'"value"',
        },
    )
    # Create the consumer group
    await redis_client.xgroup_create("my.dummy.my_event:stream",
                                     "test_group",
                                     latest_id="0")

    # Claim it in the name of another consumer
    await redis_client.xread_group("test_group",
                                   "bad_consumer",
                                   ["my.dummy.my_event:stream"],
                                   latest_ids=[0])
    # Sleep a moment to fake a short timeout
    await asyncio.sleep(0.02)

    event_transport = RedisEventTransport(
        redis_pool=redis_pool,
        consumer_group_prefix="test_group",
        consumer_name="good_consumer",
        acknowledgement_timeout=0.01,  # in ms, short for the sake of testing
        stream_use=StreamUse.PER_EVENT,
    )
    reclaimer = event_transport._reclaim_lost_messages(
        stream_names=["my.dummy.my_event:stream"],
        consumer_group="test_group",
        expected_events={"my_event"},
    )
    reclaimed_messages = [m async for m, id_ in reclaimer]
    assert len(reclaimed_messages) == 1
    assert reclaimed_messages[0].native_id
    assert type(reclaimed_messages[0].native_id) == str