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.dwrp;
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.util.Continuation;
023:
024: /**
025: * A Sleeper that works with Grizzly Continuations
026: * @author Jeanfrancois Arcand [jeanfrancois dot arcand at sun dot com]
027: */
028: public class GrizzlyContinuationSleeper implements Sleeper {
029: /**
030: * @param request The request into which we store this as an attribute
031: */
032: public GrizzlyContinuationSleeper(HttpServletRequest request) {
033: continuation = new Continuation(request);
034: }
035:
036: /* (non-Javadoc)
037: * @see org.directwebremoting.dwrp.Sleeper#goToSleep(java.lang.Runnable)
038: */
039: public void goToSleep(Runnable awakening) {
040: this .onAwakening = awakening;
041:
042: try {
043: continuation.suspend(-1);
044: } catch (Exception ex) {
045: Continuation.rethrowIfContinuation(ex);
046:
047: log.warn("Exception", ex);
048: proxy = new ThreadWaitSleeper();
049: proxy.goToSleep(onAwakening);
050: }
051: }
052:
053: /* (non-Javadoc)
054: * @see org.directwebremoting.dwrp.PollHandler.Sleeper#wakeUp()
055: */
056: public void wakeUp() {
057: if (proxy != null) {
058: proxy.wakeUp();
059: } else {
060: synchronized (continuation) {
061: if (!resumed) {
062: try {
063: /*
064: * Flush bytes if any first as before resuming the
065: * as Grizzly Comet isn't allowing writes once the
066: * continuation is resumed.
067: *
068: * This can be achieved
069: * by using Grizzly CometHandler, which isn't exposed
070: * with DWR.
071: */
072: onAwakening.run();
073: continuation.resume();
074: } catch (Exception ex) {
075: log.error("Broken reflection", ex);
076: }
077:
078: resumed = true;
079: }
080: }
081: }
082: }
083:
084: /**
085: * If continuations fail, we proxy to a Thread Wait version
086: */
087: protected ThreadWaitSleeper proxy = null;
088:
089: /**
090: * What we do when we are woken up
091: */
092: protected Runnable onAwakening;
093:
094: /**
095: * The continuation object
096: */
097: protected final Continuation continuation;
098:
099: /**
100: * Has the continuation been restarted already?
101: */
102: protected boolean resumed = false;
103:
104: /**
105: * We remember the notify conduit so we can reuse it
106: */
107: public static final String ATTRIBUTE_JETTY_CONDUIT = "org.directwebremoting.dwrp.notifyConduit";
108:
109: private static final Log log = LogFactory
110: .getLog(GrizzlyContinuationSleeper.class);
111: }
|