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
async def test_consume_events_since_id(
        loop, redis_event_transport: RedisEventTransport, redis_client,
        dummy_api):
    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'"1"',
        },
        message_id="1515000001000-0",
    )
    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'"2"',
        },
        message_id="1515000002000-0",
    )
    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'"3"',
        },
        message_id="1515000003000-0",
    )

    consumer = redis_event_transport.consume([("my.dummy", "my_event")], {},
                                             since="1515000001500-0",
                                             forever=False)

    yields = []

    async def co():
        async for m in consumer:
            yields.append(m)

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

    messages_ids = [m.native_id for m in yields if isinstance(m, EventMessage)]

    assert len(messages_ids) == 2
    assert len(yields) == 4
    assert yields[0].kwargs["field"] == "2"
    assert yields[1] is True
    assert yields[2].kwargs["field"] == "3"
    assert yields[3] is True
async def test_consume_events_since_datetime(
        loop, redis_event_transport: RedisEventTransport, redis_client,
        dummy_api):
    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'"1"',
        },
        message_id="1515000001000-0",
    )
    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'"2"',
        },
        message_id="1515000002000-0",
    )
    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'"3"',
        },
        message_id="1515000003000-0",
    )

    # 1515000001500-0 -> 2018-01-03T17:20:01.500Z
    since_datetime = datetime(2018, 1, 3, 17, 20, 1, 500)
    consumer = redis_event_transport.consume([("my.dummy", "my_event")], {},
                                             since=since_datetime,
                                             forever=False)

    yields = []

    async def co():
        async for m in consumer:
            yields.append(m)

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

    assert len(yields) == 4
    assert yields[0].kwargs["field"] == "2"
    assert yields[1] is True
    assert yields[2].kwargs["field"] == "3"
    assert yields[3] is True
示例#4
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
示例#5
0
async def test_consume_events_since_id(
    loop, redis_event_transport: RedisEventTransport, redis_client, dummy_api
):
    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'"1"',
        },
        message_id="1515000001000-0",
    )
    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'"2"',
        },
        message_id="1515000002000-0",
    )
    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'"3"',
        },
        message_id="1515000003000-0",
    )

    consumer = redis_event_transport.consume(
        [("my.dummy", "my_event")], "cg", since="1515000001500-0", forever=False, bus_client=None
    )

    events = []

    async def co():
        async for messages in consumer:
            events.extend(messages)
            await redis_event_transport.acknowledge(*messages, bus_client=None)

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

    messages_ids = [m.native_id for m in events if isinstance(m, EventMessage)]
    assert len(messages_ids) == 2
    assert len(events) == 2
    assert events[0].kwargs["field"] == "2"
    assert events[1].kwargs["field"] == "3"
    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_)
示例#8
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)
示例#9
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)