dev@grizzly.java.net

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

From: Pramod Gopinath <Pramod.Gopinath_at_Sun.COM>
Date: Sun, 24 Feb 2008 18:57:53 -0800

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


pramod-gopinaths-computer:~/work_related/grizzly_code/grizzly/tags/1_7_2/modules/jruby
pramodgopinath$ svn diff
src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
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);
+ }
+ }
+
 }