Search in sources :

Example 1 with MailboxNotification

use of com.zimbra.cs.iochannel.MailboxNotification in project zm-mailbox by Zimbra.

the class Mailbox method commitCache.

private void commitCache(MailboxChange change) {
    if (change == null) {
        return;
    }
    ChangeNotification notification = null;
    // save for notifications (below)
    PendingModifications dirty = null;
    if (change.dirty != null && change.dirty.hasNotifications()) {
        assert (lock.isWriteLockedByCurrentThread());
        assert (currentChange().writeChange);
        dirty = change.dirty;
        change.dirty = new PendingModifications();
    }
    Session source = change.octxt == null ? null : change.octxt.getSession();
    assert (!change.hasChanges() || lock.isWriteLockedByCurrentThread());
    try {
        // the mailbox data has changed, so commit the changes
        if (change.sync != null) {
            mData.trackSync = change.sync;
        }
        if (change.imap != null) {
            mData.trackImap = change.imap;
        }
        if (change.size != MailboxChange.NO_CHANGE) {
            mData.size = change.size;
        }
        if (change.itemId != MailboxChange.NO_CHANGE) {
            mData.lastItemId = change.itemId;
        }
        if (change.contacts != MailboxChange.NO_CHANGE) {
            mData.contacts = change.contacts;
        }
        if (change.changeId != MailboxChange.NO_CHANGE && change.changeId > mData.lastChangeId) {
            mData.lastChangeId = change.changeId;
            mData.lastChangeDate = change.timestamp;
        }
        if (change.accessed != MailboxChange.NO_CHANGE) {
            mData.lastWriteDate = change.accessed;
        }
        if (change.recent != MailboxChange.NO_CHANGE) {
            mData.recentMessages = change.recent;
        }
        if (change.config != null) {
            if (change.config.getSecond() == null) {
                if (mData.configKeys != null) {
                    mData.configKeys.remove(change.config.getFirst());
                }
            } else {
                if (mData.configKeys == null) {
                    mData.configKeys = new HashSet<String>(1);
                }
                mData.configKeys.add(change.config.getFirst());
            }
        }
        if (change.deletes != null && change.deletes.blobs != null) {
            // remove cached messages
            for (String digest : change.deletes.blobDigests) {
                MessageCache.purge(digest);
            }
        }
        // committed changes, so notify any listeners
        if (dirty != null && dirty.hasNotifications()) {
            try {
                // try to get a copy of the changeset that *isn't* live
                dirty = snapshotModifications(dirty);
            } catch (ServiceException e) {
                ZimbraLog.mailbox.warn("error copying notifications; will notify with live set", e);
            }
            try {
                notification = new ChangeNotification(getAccount(), dirty, change.octxt, mData.lastChangeId, change.getOperation(), change.timestamp);
            } catch (ServiceException e) {
                ZimbraLog.mailbox.warn("error getting account for the mailbox", e);
            }
        }
    } catch (RuntimeException e) {
        ZimbraLog.mailbox.error("ignoring error during cache commit", e);
    } finally {
        // keep our MailItem cache at a reasonable size
        trimItemCache();
        // make sure we're ready for the next change
        change.reset();
    }
    if (notification != null) {
        for (Session session : mListeners) {
            try {
                session.notifyPendingChanges(notification.mods, notification.lastChangeId, source);
            } catch (RuntimeException e) {
                ZimbraLog.mailbox.error("ignoring error during notification", e);
            }
        }
        // send to the message channel
        DbConnection conn = null;
        try {
            if (Zimbra.isAlwaysOn()) {
                conn = DbPool.getConnection();
                List<String> serverids = DbSession.get(conn, getId());
                for (String serverid : serverids) {
                    Server server = Provisioning.getInstance().getServerById(serverid);
                    if (server.isLocalServer()) {
                        continue;
                    }
                    MailboxNotification ntfn = MailboxNotification.create(getAccountId(), mData.lastChangeId, dirty.getSerializedBytes());
                    MessageChannel.getInstance().sendMessage(server, ntfn);
                }
            }
        } catch (ServiceException e) {
            ZimbraLog.session.warn("unable to get target server", e);
        } catch (MessageChannelException e) {
            ZimbraLog.session.warn("unable to create MailboxNotification", e);
            return;
        } catch (IOException e) {
            ZimbraLog.session.warn("unable to create MailboxNotification", e);
            return;
        } finally {
            if (conn != null) {
                conn.closeQuietly();
            }
        }
        MailboxListener.notifyListeners(notification);
    }
}
Also used : MessageChannelException(com.zimbra.cs.iochannel.MessageChannelException) Server(com.zimbra.cs.account.Server) MailboxNotification(com.zimbra.cs.iochannel.MailboxNotification) ChangeNotification(com.zimbra.cs.mailbox.MailboxListener.ChangeNotification) IOException(java.io.IOException) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) PendingModifications(com.zimbra.cs.session.PendingModifications) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) DbSession(com.zimbra.cs.db.DbSession) Session(com.zimbra.cs.session.Session) SoapSession(com.zimbra.cs.session.SoapSession)

Aggregations

ServiceException (com.zimbra.common.service.ServiceException)1 AccountServiceException (com.zimbra.cs.account.AccountServiceException)1 Server (com.zimbra.cs.account.Server)1 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)1 DbSession (com.zimbra.cs.db.DbSession)1 MailboxNotification (com.zimbra.cs.iochannel.MailboxNotification)1 MessageChannelException (com.zimbra.cs.iochannel.MessageChannelException)1 ChangeNotification (com.zimbra.cs.mailbox.MailboxListener.ChangeNotification)1 PendingModifications (com.zimbra.cs.session.PendingModifications)1 Session (com.zimbra.cs.session.Session)1 SoapSession (com.zimbra.cs.session.SoapSession)1 IOException (java.io.IOException)1