use of com.zimbra.cs.servlet.continuation.ResumeContinuationListener in project zm-mailbox by Zimbra.
the class ZimbraSoapContext method beginWaitForNotifications.
public boolean beginWaitForNotifications(Continuation continuation, boolean includeDelegates) throws ServiceException {
mWaitForNotifications = true;
continuationResume = new ResumeContinuationListener(continuation);
Session session = SessionCache.lookup(mSessionInfo.sessionId, mAuthTokenAccountId);
if (!(session instanceof SoapSession))
return false;
SoapSession ss = (SoapSession) session;
SoapSession.RegisterNotificationResult result = ss.registerNotificationConnection(mSessionInfo.getPushChannel(!includeDelegates));
switch(result) {
case NO_NOTIFY:
return false;
case DATA_READY:
return false;
case BLOCKING:
return true;
default:
return false;
}
}
use of com.zimbra.cs.servlet.continuation.ResumeContinuationListener in project zm-mailbox by Zimbra.
the class WaitSetRequest method staticHandle.
public static Element staticHandle(Element request, Map<String, Object> context, Element response, boolean adminAllowed) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
HttpServletRequest servletRequest = (HttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
String waitSetId = request.getAttribute(MailConstants.A_WAITSET_ID);
String lastKnownSeqNo = request.getAttribute(MailConstants.A_SEQ);
boolean block = request.getAttributeBool(MailConstants.A_BLOCK, false);
Callback cb = (Callback) servletRequest.getAttribute(VARS_ATTR_NAME);
if (cb == null) {
// Initial
Continuation continuation = ContinuationSupport.getContinuation(servletRequest);
cb = new Callback();
cb.continuationResume = new ResumeContinuationListener(continuation);
servletRequest.setAttribute(VARS_ATTR_NAME, cb);
String defInterestStr = null;
if (waitSetId.startsWith(WaitSetMgr.ALL_ACCOUNTS_ID_PREFIX)) {
WaitSetMgr.checkRightForAllAccounts(zsc);
// default interest types required for "All" waitsets
defInterestStr = request.getAttribute(MailConstants.A_DEFTYPES);
Set<MailItem.Type> defaultInterests = WaitSetRequest.parseInterestStr(defInterestStr, EnumSet.noneOf(MailItem.Type.class));
cb.ws = WaitSetMgr.lookupOrCreateForAllAccts(zsc.getRequestedAccountId(), waitSetId, defaultInterests, lastKnownSeqNo);
} else {
cb.ws = WaitSetMgr.lookup(waitSetId);
}
if (cb.ws == null)
throw AdminServiceException.NO_SUCH_WAITSET(waitSetId);
WaitSetMgr.checkRightForOwnerAccount(cb.ws, zsc.getRequestedAccountId());
List<WaitSetAccount> add = parseAddUpdateAccounts(zsc, request.getOptionalElement(MailConstants.E_WAITSET_ADD), cb.ws.getDefaultInterest());
List<WaitSetAccount> update = parseAddUpdateAccounts(zsc, request.getOptionalElement(MailConstants.E_WAITSET_UPDATE), cb.ws.getDefaultInterest());
List<String> remove = parseRemoveAccounts(zsc, request.getOptionalElement(MailConstants.E_WAITSET_REMOVE));
///////////////////
// workaround for 27480: load the mailboxes NOW, before we grab the waitset lock
List<Mailbox> referencedMailboxes = new ArrayList<Mailbox>();
for (WaitSetAccount acct : add) {
try {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(acct.getAccountId(), MailboxManager.FetchMode.AUTOCREATE);
referencedMailboxes.add(mbox);
} catch (ServiceException e) {
ZimbraLog.session.debug("Caught exception preloading mailbox for waitset", e);
}
}
for (WaitSetAccount acct : update) {
try {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(acct.getAccountId(), MailboxManager.FetchMode.AUTOCREATE);
referencedMailboxes.add(mbox);
} catch (ServiceException e) {
ZimbraLog.session.debug("Caught exception preloading mailbox for waitset", e);
}
}
// the server in a very fast loop (they should be using the 'block' mode)
try {
Thread.sleep(INITIAL_SLEEP_TIME_MILLIS);
} catch (InterruptedException ex) {
}
cb.errors.addAll(cb.ws.removeAccounts(remove));
synchronized (cb.ws) {
// bug 28190: always grab the WS lock before the CB lock.
synchronized (cb) {
cb.errors.addAll(cb.ws.doWait(cb, lastKnownSeqNo, add, update));
// the ws until we release the cb lock!
if (cb.completed)
block = false;
}
}
if (block) {
// bit.
try {
Thread.sleep(NODATA_SLEEP_TIME_MILLIS);
} catch (InterruptedException ex) {
}
synchronized (cb) {
if (!cb.completed) {
// don't wait if it completed right away
long timeout = getTimeoutMillis(request, adminAllowed);
if (ZimbraLog.soap.isTraceEnabled())
ZimbraLog.soap.trace("Suspending <WaitSetRequest> for %dms", timeout);
cb.continuationResume.suspendAndUndispatch(timeout);
}
}
}
}
// if we got here, then we did *not* execute a jetty RetryContinuation,
// soooo, we'll fall through and finish up at the bottom
// clear the
cb.ws.doneWaiting();
response.addAttribute(MailConstants.A_WAITSET_ID, waitSetId);
if (cb.canceled) {
response.addAttribute(MailConstants.A_CANCELED, true);
} else if (cb.completed) {
response.addAttribute(MailConstants.A_SEQ, cb.seqNo);
for (String s : cb.signalledAccounts) {
Element saElt = response.addElement(MailConstants.E_A);
saElt.addAttribute(MailConstants.A_ID, s);
}
} else {
// timed out....they should try again
response.addAttribute(MailConstants.A_SEQ, lastKnownSeqNo);
}
encodeErrors(response, cb.errors);
return response;
}
Aggregations