Search before reporting
Read release policy
User environment
Broker 4.0.13, Go client consumer on a Shared subscription. The code looks the same on master.
Issue Description
Producer has chunking enabled (messages can be tens of MB, so most of them get chunked),
consumed by a Shared subscription.
- Publish a chunked message, chunks 0..2 land on entries 100, 101, 102.
- Consumer gets chunks 0 and 1 and acks them, mark-delete moves to 101.
- Consumer restarts. A topic unload or broker restart has the same effect.
- Entry 102 (chunk 2) is next in line.
From that point the subscription never delivers anything again. Backlog grows, no error, no
warning. pulsar-admin topics skip on that one entry and everything resumes instantly.
What did you expect to see
The leftover chunk either delivered (clients already know how to discard an incomplete chunked
message) or skipped, and the rest of the topic dispatched normally.
What did you see instead
Nothing in the broker logs at all, which is why this took us so long to find.
SharedConsumerAssignor.getConsumerForUuid() looks the uuid up in uuidToConsumer. That map is
in-memory per dispatcher and only ever written when chunk 0 is assigned, so after the restart it
is empty and chunk 2 hits:
if (metadata.getChunkId() != 0) {
// Not the first chunk, skip it
return null;
}
null makes assign() hand the entry to unassignedMessageProcessor, which the dispatcher wires
to addEntryToReplay, so it goes into redeliveryMessages. Next round the exact same thing
happens, because chunk 0 is acked and will never be read again to recreate the mapping. The entry stays in the replay queue.
Error messages
Reproducing the issue
I created a a unittest and patch.
Additional information
Please backport to 4.0 LTS
Are you willing to submit a PR?
Search before reporting
Read release policy
User environment
Broker 4.0.13, Go client consumer on a Shared subscription. The code looks the same on master.
Issue Description
Producer has chunking enabled (messages can be tens of MB, so most of them get chunked),
consumed by a Shared subscription.
From that point the subscription never delivers anything again. Backlog grows, no error, no
warning.
pulsar-admin topics skipon that one entry and everything resumes instantly.What did you expect to see
The leftover chunk either delivered (clients already know how to discard an incomplete chunked
message) or skipped, and the rest of the topic dispatched normally.
What did you see instead
Nothing in the broker logs at all, which is why this took us so long to find.
SharedConsumerAssignor.getConsumerForUuid()looks the uuid up inuuidToConsumer. That map isin-memory per dispatcher and only ever written when chunk 0 is assigned, so after the restart it
is empty and chunk 2 hits:
nullmakesassign()hand the entry tounassignedMessageProcessor, which the dispatcher wiresto
addEntryToReplay, so it goes intoredeliveryMessages. Next round the exact same thinghappens, because chunk 0 is acked and will never be read again to recreate the mapping. The entry stays in the replay queue.
Error messages
Reproducing the issue
I created a a unittest and patch.
Additional information
Please backport to 4.0 LTS
Are you willing to submit a PR?