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);
}
}
Aggregations