001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.impl;
017:
018: import javax.servlet.http.HttpServletRequest;
019:
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.directwebremoting.extend.Sleeper;
023: import org.directwebremoting.util.Continuation;
024:
025: /**
026: * A Sleeper that works with Grizzly Continuations
027: * @author Jeanfrancois Arcand [jeanfrancois dot arcand at sun dot com]
028: */
029: public class GrizzlyContinuationSleeper implements Sleeper {
030: /**
031: * @param request The request into which we store this as an attribute
032: */
033: public GrizzlyContinuationSleeper(HttpServletRequest request) {
034: continuation = new Continuation(request);
035: }
036:
037: /* (non-Javadoc)
038: * @see org.directwebremoting.dwrp.Sleeper#goToSleep(java.lang.Runnable)
039: */
040: public void goToSleep(Runnable awakening) {
041: this .onAwakening = awakening;
042:
043: try {
044: continuation.suspend(-1);
045: } catch (Exception ex) {
046: Continuation.rethrowIfContinuation(ex);
047:
048: log.warn("Exception", ex);
049: proxy = new ThreadWaitSleeper();
050: proxy.goToSleep(onAwakening);
051: }
052: }
053:
054: /* (non-Javadoc)
055: * @see org.directwebremoting.dwrp.PollHandler.Sleeper#wakeUp()
056: */
057: public void wakeUp() {
058: if (proxy != null) {
059: proxy.wakeUp();
060: } else {
061: synchronized (continuation) {
062: if (!resumed) {
063: try {
064: /*
065: * Flush bytes if any first as before resuming the
066: * as Grizzly Comet isn't allowing writes once the
067: * continuation is resumed.
068: *
069: * This can be achieved
070: * by using Grizzly CometHandler, which isn't exposed
071: * with DWR.
072: */
073: onAwakening.run();
074: continuation.resume();
075: } catch (Exception ex) {
076: log.error("Broken reflection", ex);
077: }
078:
079: resumed = true;
080: }
081: }
082: }
083: }
084:
085: /**
086: * If continuations fail, we proxy to a Thread Wait version
087: */
088: protected ThreadWaitSleeper proxy = null;
089:
090: /**
091: * What we do when we are woken up
092: */
093: protected Runnable onAwakening;
094:
095: /**
096: * The continuation object
097: */
098: protected final Continuation continuation;
099:
100: /**
101: * Has the continuation been restarted already?
102: */
103: protected boolean resumed = false;
104:
105: /**
106: * We remember the notify conduit so we can reuse it
107: */
108: public static final String ATTRIBUTE_JETTY_CONDUIT = "org.directwebremoting.dwrp.notifyConduit";
109:
110: private static final Log log = LogFactory
111: .getLog(GrizzlyContinuationSleeper.class);
112: }
|