Search in sources :

Example 1 with PurgeFromIncomingDataSource

use of com.zimbra.cs.purge.PurgeFromIncomingDataSource in project zm-mailbox by Zimbra.

the class MailItemImport method purgeIfNecessary.

protected void purgeIfNecessary(OperationContext octxt, CurrentUsage usage, ParsedMessage pm) throws ServiceException {
    if (!mbox.getAccount().isFeatureDataSourcePurgingEnabled()) {
        return;
    }
    if (usage == null) {
        usage = new CurrentUsage();
    }
    // first, see if the incoming message is part of an existing conversation thread
    Integer thisConvId = null;
    if (pm != null) {
        List<Conversation> matchingConvs = mbox.lookupConversation(pm);
        if (matchingConvs.size() > 0) {
            Collections.sort(matchingConvs, new MailItem.SortSizeDescending());
            thisConvId = matchingConvs.remove(0).getId();
        }
        // from the purge queue
        if (thisConvId != null) {
            if (thisConvId < 0) {
                // the incoming message is the second message in a conversation, so the PurgeableConv entry in the queue
                // will be under the ID of the first message
                ConversationPurgeQueue.removeAllNodesById(-1 * thisConvId);
            } else {
                // the incoming message is part of a conversation that already has a dedicated ID, so the PurgeableConv
                // entry will be under the ID of the conversation
                ConversationPurgeQueue.removeAllNodesById(thisConvId);
            }
        }
    }
    if (usage.spaceToFreeUp > 0 && !usage.sizeOverQuota) {
        // see if a purge process is already running
        PurgeLock purgeLock = getPurgeLock(mbox.getAccount());
        try {
            synchronized (purgeLock) {
                if (purgeLock.isLocked()) {
                    //wait and acquire purge lock
                    purgeLock.lock();
                    //wait and acquire purge lock
                    ;
                    //could have changed since previous purge
                    usage.calculate();
                    if (usage.spaceToFreeUp <= 0) {
                        return;
                    }
                } else {
                    purgeLock.lock();
                }
            }
            DataSourcePurge purge;
            if (usage.overTotalQuota) {
                purge = new PurgeFromAllDataSources(mbox);
            } else {
                purge = new PurgeFromIncomingDataSource(mbox);
            }
            purge.purgeConversations(octxt, dataSource, usage.spaceToFreeUp, thisConvId);
            usage.calculate();
            int attempt = 0;
            while (usage.spaceToFreeUp > 0 && !usage.sizeOverQuota && attempt < MAX_PURGE_ATTEMPTS) {
                attempt++;
                // This is possible in some edge cases, such as when some purged conversations
                // spanned multiple data sources, which would make the actual purged size less than
                // the conversation size.
                ZimbraLog.datasource.warn(String.format("still need to free up %d bytes!", usage.spaceToFreeUp));
                purge.purgeConversations(octxt, dataSource, usage.spaceToFreeUp, thisConvId);
                usage.calculate();
            }
        } finally {
            purgeLock.unlock();
        }
    }
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) PurgeFromIncomingDataSource(com.zimbra.cs.purge.PurgeFromIncomingDataSource) PurgeFromAllDataSources(com.zimbra.cs.purge.PurgeFromAllDataSources) Conversation(com.zimbra.cs.mailbox.Conversation) DataSourcePurge(com.zimbra.cs.purge.DataSourcePurge)

Aggregations

Conversation (com.zimbra.cs.mailbox.Conversation)1 MailItem (com.zimbra.cs.mailbox.MailItem)1 DataSourcePurge (com.zimbra.cs.purge.DataSourcePurge)1 PurgeFromAllDataSources (com.zimbra.cs.purge.PurgeFromAllDataSources)1 PurgeFromIncomingDataSource (com.zimbra.cs.purge.PurgeFromIncomingDataSource)1