[bug] `pubrel` delivery re-try causes `no such packet` error
See original GitHub issueSystem Information
- Aedes: 0.42.5
- NodeJS: v14.15.4
- OS: MacOS 10.15.7
- Arch: x86_64
Describe the bug
When receiving pubrel
packet for a message that’s been already fully processed from the broker’s point of view, the broker logs no such packet
error and disconnects. The client. If the client didn’t receive the initial pubcomp
and wants to resend the pubrel
upon reconnection, this will lead to a re-connection loop, where the client would connect, send pubrel
, get disconnected, re-connect, send pubrel
, get disconnected and so on.
To Reproduce
Run the publish QoS 2, pubrel delivery retry
test I’ve added here.
Expected behavior
The broker should neither emit any error nor disconnect the client when receiving pubrel
packet for already pubcomp
ed message. It should send the pubcomp
once more instead.
Additional context According to the MQTT spec the client
MUST re-send any unacknowledged PUBLISH Packets (where QoS > 0) and PUBREL Packets using their original Packet Identifiers
so conforming to this should not cause any errors.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:8 (5 by maintainers)
Redis: https://github.com/moscajs/aedes-persistence-redis/blob/master/persistence.js#L524 Mongodb: https://github.com/moscajs/aedes-persistence-mongodb/blob/master/persistence.js#L613
We should also patch persistence to return something that allow to distinguish errors correctly.
I also noticed that not just the error message changes but also mongo returns null and client as params where redis returns only the error. I think the steps here are to firstly add a test to abstract test of aedes persistence that checks the error returned when there is no packet found is the same across all persistences then patch all them
I think replying with
pubcomp
topubrel
for message we don’t have in the persistence is the only viable option, unless I’m missing something. Not sure though if it should be the same if we have the message in the persistence, but we haven’tpubrec
ed it yet - in such situation thepubrel
would be unexpected. But maybe there’s no need to bother with this.I wouldn’t like to ignore all the errors. I guess there could be some other errors like not having the active connection to the underlying redis (or whatever persistence) and in such cases the error should be properly propagated, not suppressed. Ignoring the
no such packet
error specifically could work here, but I’m a bit afraid on relying on this hardcoded string. Are all the persistence implementations guaranteed to use the very same string?