package net.sf.jruby.rails.asyncweb.service;
import java.io.IOException;
import net.sf.jruby.rails.asyncweb.config.RailsConfig;
import net.sf.jruby.rails.asyncweb.ruby.RubyHttpRequest;
import net.sf.jruby.rails.asyncweb.ruby.RubyHttpRequestMetaClass;
import net.sf.jruby.rails.asyncweb.ruby.RubyHttpResponse;
import net.sf.jruby.rails.asyncweb.ruby.RubyHttpResponseMetaClass;
import org.jruby.IRuby;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.libraries.StringIOLibrary;
import org.jruby.runtime.builtin.IRubyObject;
import org.safehaus.asyncweb.http.HttpRequest;
import org.safehaus.asyncweb.http.HttpResponse;
import org.safehaus.asyncweb.http.HttpService;
import org.safehaus.asyncweb.http.ResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RailsDispatchService implements HttpService {
private static final Logger LOGGER = LoggerFactory.getLogger(RailsFileService.class.getName());
private IRubyObject asyncwebDispatcher = null;
private RailsConfig railsConfig = null;
private RubyHttpRequestMetaClass requestMetaClass = null;
private RubyHttpResponseMetaClass responseMetaClass = null;
private IRuby ruby = null;
public void handleRequest(HttpRequest request) {
try {
HttpResponse response = request.createHttpResponse();
IRubyObject rubyReq = new RubyHttpRequest(ruby, requestMetaClass, request);
IRubyObject rubyRes = new RubyHttpResponse(ruby, responseMetaClass, response);
if (LOGGER.isDebugEnabled()) {
long start = System.nanoTime();
asyncwebDispatcher.callMethod("dispatch", new IRubyObject[] { rubyReq, rubyRes });
LOGGER.debug("AsyncWebDispatcher#dispatch(req, res) takes {} nanoseconds", System.nanoTime() - start);
} else {
asyncwebDispatcher.callMethod("dispatch", new IRubyObject[] { rubyReq, rubyRes });
}
request.commitResponse(response);
} catch (RuntimeException e) {
if (LOGGER.isErrorEnabled())
LOGGER.error(e.getMessage(), e);
request.commitErrorResponse(ResponseStatus.INTERNAL_SERVER_ERROR);
}
}
public void setRailsConfig(RailsConfig railsConfig) {
this.railsConfig = railsConfig;
}
public void start() {
try {
if (LOGGER.isDebugEnabled())
LOGGER.debug("{}#start()", getClass().getName());
if (LOGGER.isDebugEnabled())
LOGGER.debug("initializing ruby");
ruby = Ruby.getDefaultInstance();
ruby.getLoadService().init(railsConfig.getLoadPathList());
if (LOGGER.isDebugEnabled())
LOGGER.debug("loading asyncweb.rb");
ruby.getLoadService().require("asyncweb.rb");
if (LOGGER.isDebugEnabled())
LOGGER.debug("loading {}/config/environment.rb", railsConfig.getRailsRoot());
ruby.getLoadService().require(railsConfig.getRailsRoot() + "/config/environment");
if (LOGGER.isDebugEnabled())
LOGGER.debug("loading builtin jruby-rails libralies");
new StringIOLibrary().load(ruby);
requestMetaClass = new RubyHttpRequestMetaClass(ruby);
requestMetaClass.initializeClass();
responseMetaClass = new RubyHttpResponseMetaClass(ruby);
responseMetaClass.initializeClass();
RubyClass asyncWebDispatcherClass = ruby.getClass("AsyncWebDispatcher");
asyncwebDispatcher = asyncWebDispatcherClass.newInstance(new IRubyObject[] {});
} catch (IOException e) {
if (LOGGER.isDebugEnabled())
LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
public void stop() {
if (LOGGER.isDebugEnabled())
LOGGER.debug("{}#stop()", getClass().getName());
ruby.tearDown();
}
}