In NAKACK2.up(MessageBatch batch):
- Assume we have a batch of 5 copies (duplicates) of message A5
- When we call Table.add(List), it returns true if at least one message was added
- Say the first A5 message was added, but the others were discarded
- If the message is OOB, then for each message, we
- Check if we can set OOB_DELIVERED
- If true, we pass it up, else we discard it
- However, because every A5 message is a copy, we'll be able to set the flag on all 5 messages and pass all messages up !
- This means we're allowing the 4 duplicate messages to pass up !
Note that this does not happen when we don't batch messages as every messages is added individually, and 'added' will therefore be true or false.
Also, if we're the sender of a message (loopback), then we'll fetch, for each seqno, the corresponding message from the table and therefore setTransientFlagIfAbsent() will only return true once for the same message, as we're fetching the same message for the same seqno.
- Add another Table.add(List) method which removes all messages that weren't added to the table from the list(because they were dupes)
- This method would only get called if the message batch is OOB
- If OOB and at least 1 message was added, we can now pass all messages from the remaining list up and set OOB_DELIVERED
- As the messages in the list have been added to the table (keyed by seqno), if some other thread wants to add a message with the same seqno, it'll fail as OOB_DELIVERED is already set and we're dealing with the same message