dev@grizzly.java.net

Re: Issue were subsequent requests were not using the correct values from the Request object

From: Pramod Gopinath <Pramod.Gopinath_at_Sun.COM>
Date: Mon, 25 Feb 2008 11:49:24 -0800

Hi Jeanfrancois
  Here is the .diff file (created by using the command : svn diff
src/main/java/com/sun/grizzly/jruby/RailsAdapter.java >
RailsAdapter.diff) as per UR request.

Thanks
Pramod

Pramod Gopinath wrote:
> The problem was with some of the environment variables that were being
> set on the rails runtime. The behavior was that after first round of
> requests IO reads were not happening any more, but the stdin, stdout
> stuff was getting setup properly. Issue 4228
> <https://glassfish.dev.java.net/issues/show_bug.cgi?id=4228> contains
> more details. This issue has also manifested in bugs
> <http://rubyforge.org/tracker/?atid=21080&group_id=5450&func=browse>
> that were reported on RubyForge in terms of XHttpRequests which were
> not getting reset in subsequent requests.
>
> Additionally have made one more change to display a meaningful message
> where there are no runtimes available to satisfy a request. Currently
> if there are no runtimes available to satisfy a request we just print
> "null" out, which is not helpful in any way.
>
>
> The code changes are in
> modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java.
> The svn diff is provided below :
>
> Have tested this using JRuby 1.0.3 and JRuby 1.1RC2 using Rails 1.2.6
> and Rails 2.0.2 respectively.
>
> Thanks
> Pramod Gopinath




Index: src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
===================================================================
--- src/main/java/com/sun/grizzly/jruby/RailsAdapter.java (revision 856)
+++ src/main/java/com/sun/grizzly/jruby/RailsAdapter.java (working copy)
@@ -27,10 +27,12 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.util.Map;
 
 import org.jruby.Ruby;
 import org.jruby.RubyException;
 import org.jruby.RubyIO;
+import org.jruby.RubyHash;
 import org.jruby.ast.Node;
 import org.jruby.exceptions.RaiseException;
 import org.jruby.javasupport.JavaEmbedUtils;
@@ -43,6 +45,7 @@
 import com.sun.grizzly.tcp.Request;
 import com.sun.grizzly.tcp.Response;
 import com.sun.grizzly.tcp.http11.InternalOutputBuffer;
+import java.util.HashMap;
 
 /**
  * Adapter implementation that bridge JRuby on Rails with Grizzly.
@@ -58,6 +61,7 @@
     private RubyObjectPool pool = null;
     
     private RubyRuntimeAsyncFilter asyncFilter;
+ private Map environment;
     
     public RailsAdapter( RubyObjectPool pool) {
         super(pool.getRailsRoot() + "/public");
@@ -86,31 +90,10 @@
         try {
             runtime = pool.borrowRuntime();
             if (runtime == null){
- throw new IllegalStateException();
+ throw new IllegalStateException(
+ "No Rails Instances available to satisfy the current request");
             }
-
- req.doRead(rt.readChunk);
- ((InternalOutputBuffer)res.getOutputBuffer()).commit();
- res.setCommitted(true);
-
- IRubyObject reqObj = JavaEmbedUtils.javaToRuby(runtime, req);
- IRubyObject loggerObj = JavaEmbedUtils.javaToRuby(runtime, SelectorThread.logger());
-
- OutputStream os =
- ((InternalOutputBuffer)res.getOutputBuffer()).getOutputStream();
-
- RubyIO iObj = new RubyIO(runtime, rt.inputStream);
- RubyIO oObj = new RubyIO(runtime, os);
-
- runtime.defineReadonlyVariable("$req", reqObj);
- runtime.defineReadonlyVariable("$stdin", iObj);
- runtime.defineReadonlyVariable("$stdout", oObj);
- runtime.defineReadonlyVariable("$logger", loggerObj);
-
- if (contextRoot!=null && !contextRoot.equals("/")) {
- runtime.defineReadonlyVariable("$root",
- JavaEmbedUtils.javaToRuby(runtime, contextRoot));
- }
+ loadRuntimeEnvironment(runtime, res, rt);
             (JavaEmbedUtils.newRuntimeAdapter()).eval(runtime, getDispatcherString());
         } catch (RaiseException e) {
             RubyException exception = e.getException();
@@ -146,4 +129,45 @@
         return completeText.toString();
     }
 
+ private void loadRuntimeEnvironment(Ruby runtime, Response res,
+ DynamicContentAdapter.RequestTupple rt) {
+ RubyHash env = (RubyHash) runtime.getObject().getConstant("ENV");
+ if (environment == null) {
+ IRubyObject loggerObj = JavaEmbedUtils.javaToRuby(runtime, SelectorThread.logger());
+ runtime.defineReadonlyVariable("$logger", loggerObj);
+
+ if (contextRoot!=null && !contextRoot.equals("/")) {
+ runtime.defineReadonlyVariable("$root",
+ JavaEmbedUtils.javaToRuby(runtime, contextRoot));
+ }
+
+ environment = new HashMap();
+ environment.putAll(env);
+ } else {
+ env.clear();
+ env.putAll(environment);
+ }
+
+ try {
+ RubyIO iObj = new RubyIO(runtime, rt.inputStream);
+ runtime.defineReadonlyVariable("$stdin", iObj);
+
+ ((InternalOutputBuffer)res.getOutputBuffer()).commit();
+ res.setCommitted(true);
+
+ Request req = rt.req;
+ req.doRead(rt.readChunk);
+ IRubyObject reqObj = JavaEmbedUtils.javaToRuby(runtime, req);
+ runtime.defineReadonlyVariable("$req", reqObj);
+
+ OutputStream os =
+ ((InternalOutputBuffer)res.getOutputBuffer()).getOutputStream();
+ RubyIO oObj = new RubyIO(runtime, os);
+ runtime.defineReadonlyVariable("$stdout", oObj);
+ } catch (java.io.IOException e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace(System.err);
+ }
+ }
+
 }