René Cordier created JAMES-3057:
-----------------------------------

             Summary: Implement a MailboxMapper::create method
                 Key: JAMES-3057
                 URL: https://issues.apache.org/jira/browse/JAMES-3057
             Project: James Server
          Issue Type: Improvement
          Components: mailbox
            Reporter: René Cordier


*Why*

Currently, creating and renaming a mailbox trigger the same operation.

Looking at CassandraMapper, we got the following code:

{code:java}
    private boolean trySave(Mailbox cassandraMailbox, CassandraId cassandraId) {
        boolean isCreated = 
mailboxPathV2DAO.save(cassandraMailbox.generateAssociatedPath(), 
cassandraId).block();
        if (isCreated) {
            Optional<Mailbox> simpleMailbox = 
retrieveMailbox(cassandraId).blockOptional();
            simpleMailbox.ifPresent(mbx -> 
mailboxPathV2DAO.delete(mbx.generateAssociatedPath()).block());
            mailboxDAO.save(cassandraMailbox).block();
        }
        return isCreated;
    }
{code}

This means that upon create we try to perform a useless read to see if the 
mailbox previously existed.

Such read-before-writes is a Cassandra anti-pattern that should be avoided. 

If this read fails, then the mailbox table is never updated, and we have an 
inconsistency.

*Proposal*

We need to have a new method in the MailboxMapper:

{code:java}
// @throws if exists
Mailbox create(MailboxPath path, UidValidity uidValidity) throws 
MailboxException;
{code}

We will provide a default method leveraging existing `save`.

We will implement it in `mailbox/cassandra` in order to skip the read before 
writes:

{code:java}
    // Some comments here
    private boolean tryCreate(MailboxPath path, UidValidity uidValidity) {
        // Generate mailbox
        boolean isCreated = 
mailboxPathV2DAO.save(cassandraMailbox.generateAssociatedPath(), 
cassandraId).block();
        if (isCreated) {
            mailboxDAO.save(cassandraMailbox).block();
        }
        // TODO Reactor chain this?
        return isCreated;
    }
{code}

Unit test have to be written for MailboxMapper::create.

StoreMailboxManager::performConcurrentMailboxCreation needs to be adapted, and 
StoreMailboxManager::doCreateMailbox removed.

*Kisscool refactoring effect*

Maybe `Mailbox.mailboxId` can be made final once this change done. :-)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

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

Reply via email to