Revision: 1230
Author: dhanji
Date: Mon Sep 13 15:18:14 2010
Log: Early support for thread-continuation of servlet request.
http://code.google.com/p/google-guice/source/detail?r=1230
Added:
/trunk/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java
Modified:
/trunk/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
=======================================
--- /dev/null
+++
/trunk/extensions/servlet/src/com/google/inject/servlet/ContinuingHttpServletRequest.java
Mon Sep 13 15:18:14 2010
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import com.google.inject.OutOfScopeException;
+import com.google.inject.internal.util.Maps;
+import java.io.IOException;
+import java.util.Map;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+/**
+ * A wrapper for requests that makes requests immutable, taking a snapshot
+ * of the original request.
+ *
+ * @author [email protected] (Dhanji R. Prasanna)
+ */
+class ContinuingHttpServletRequest extends HttpServletRequestWrapper {
+
+ // We clear out the attributes as they are mutable and not thread-safe.
+ private final Map<String, Object> attributes = Maps.newHashMap();
+
+ public ContinuingHttpServletRequest(HttpServletRequest request) {
+ super(request);
+ }
+
+ @Override public HttpSession getSession() {
+ throw new OutOfScopeException("Cannot access the session in a
continued request");
+ }
+
+ @Override public HttpSession getSession(boolean create) {
+ throw new UnsupportedOperationException("Cannot access the session in
a continued request");
+ }
+
+ @Override public ServletInputStream getInputStream() throws IOException {
+ throw new UnsupportedOperationException("Cannot access raw request on
a continued request");
+ }
+
+ @Override public void setAttribute(String name, Object o) {
+ attributes.put(name, o);
+ }
+
+ @Override public void removeAttribute(String name) {
+ attributes.remove(name);
+ }
+
+ @Override public Object getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ @Override public Cookie[] getCookies() {
+ // TODO(dhanji): Cookies themselves are mutable. Is this a problem?
+ return super.getCookies().clone();
+ }
+}
=======================================
---
/trunk/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
Wed Aug 12 12:24:11 2009
+++
/trunk/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
Mon Sep 13 15:18:14 2010
@@ -17,9 +17,10 @@
package com.google.inject.servlet;
import com.google.inject.Key;
+import com.google.inject.OutOfScopeException;
import com.google.inject.Provider;
import com.google.inject.Scope;
-
+import java.util.concurrent.Callable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -103,4 +104,53 @@
return "ServletScopes.SESSION";
}
};
-}
+
+ /**
+ * Wraps the given callable in a contextual callable that "continues" the
+ * HTTP request in another thread. This acts as a way of transporting
+ * request context data from the request processing thread to to worker
+ * threads.
+ * <p>
+ * There are some limitations:
+ * <ul>
+ * <li>Derived objects (i.e. anything marked @RequestScoped will not be
+ * transported.</li>
+ * <li>State changes to the HttpServletRequest after this method is
called
+ * will not be seen in the continued thread.</li>
+ * <li>Only the HttpServletRequest, ServletContext and request
parameter
+ * map are available in the continued thread. The response and
session
+ * are not available.</li>
+ * </ul>
+ *
+ * @param callable code to be executed in another thread, which depends
on
+ * the request scope.
+ * @return a callable that will invoke the given callable, making the
request
+ * context available to it.
+ * @throws OutOfScopeException if this method is called from a
non-request
+ * thread, or if the request has completed.
+ */
+ public static <T> Callable<T> continueRequest(final Callable<T>
callable) {
+ return new Callable<T>() {
+ private HttpServletRequest request =
+ new ContinuingHttpServletRequest(GuiceFilter.getRequest());
+
+ public T call() throws Exception {
+ GuiceFilter.Context context = GuiceFilter.localContext.get();
+ if (null == context) {
+ // Only set up the request continuation if we're running in a
+ // new vanilla thread.
+ GuiceFilter.localContext.set(new GuiceFilter.Context(request,
null));
+ }
+ try {
+ return callable.call();
+ } finally {
+
+ // Clear the copied context if we set one up.
+ if (null == context) {
+ GuiceFilter.localContext.remove();
+ }
+ }
+ }
+ };
+ }
+}
--
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en.