prosgarz35 commented on code in PR #3200:
URL: https://github.com/apache/james-project/pull/3200#discussion_r4090897559


##########
mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/DeleteMessageListenerContract.java:
##########
@@ -311,6 +311,27 @@ void deleteMessageShouldCleanUpThreadData() throws 
Exception {
         });
     }
 
+    @Test
+    void 
deleteIfUnreferencedShouldNotDeleteBlobWhenConcurrentReferenceExists() throws 
Exception {
+        MessageManager.AppendResult appendResult = 
inboxManager.appendMessage(MessageManager.AppendCommand.builder()
+            
.build(ClassLoaderUtils.getSystemResourceAsByteArray("eml/emailWithOnlyAttachment.eml")),
 session);
+        PostgresMessageId messageId = (PostgresMessageId) 
appendResult.getId().getMessageId();
+        BlobId messageBodyBlobId = 
postgresMessageDAO.getBodyBlobId(messageId).block();
+
+        // Simulate concurrent reference by copying message to other mailbox
+        mailboxManager.copyMessages(MessageRange.all(), inboxManager.getId(), 
otherBoxManager.getId(), session);
+
+        // Attempt conditional delete - should not delete row nor return 
blobId because of concurrent reference
+        Optional<BlobId> deletedBlobId = 
postgresMessageDAO.deleteIfUnreferenced(messageId).block();

Review Comment:
       Thanks for the thorough review, @quantranhong1999! You're completely 
right on both points:
   
       1. **Deletion order & retry**: Deleting the database row first indeed 
breaks event retryability in `DeleteMessageListener`—if `blobStore.delete()` or 
attachment cleanup fails due to transient storage/network issues, subsequent
     retries won't be able to retrieve the message representation and remaining 
blobs/attachments will become unrecoverable orphans. Keeping the standard James 
order (deleting blobs/attachments first and removing the message database row
     last) preserves idempotency and allows retries to finish cleanup.
   
       2. **Test scenario**: Agreed, the test simply called 
`deleteIfUnreferenced` directly against a copied message without actually 
running the listener or reproducing a true concurrent race. Moreover,
     `deleteMessageListenerShouldNotDeleteReferencedBlob()` already verifies 
that referenced messages/blobs are not deleted when other references exist.
   
       I will revert the premature row deletion and clean this up.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to