There are many ways to store sessions in Ruby on Rails, but by using JRuby, we get another option that I think supersedes the common solutions... Using the Java Server's built in session store.
config/initializers/session_store.rb
Cookie Store: This is not very secure, limited in size, and sends a lot of data back and forth to the client. It is strongly recommended to not use this for production systems.
File Store: Stores sessions on the file system. Every cookie access involves file system IO. Does not support clustering by default but can be achieved through a SAN or shared storage.
ActiveRecord: Stores sessions in the database. Slow due to database IO. Natively supports clustering.
Memcached: Stores sessions in Memcached instance. Very popular and works well with clusters. Can run into RAM issues on systems with lots of users. Requires an instance of Memcached running.
Java Servlet Store: Works just like your other Java applications. Java Servers can be configured to cluster sessions. Uses the JSESSIONID cookie or url param (in Tomcat)
First... The implementation
This is assuming that you are running JRuby and using a tool like warbler to deploy to a Java server like Tomcat.config/initializers/session_store.rb
# check if we're running in a java container
if defined?($servlet_context)
require 'action_controller/session/java_servlet_store'
# tell rails to use the java container's session store
ActionController::Base.session_store = :java_servlet_store
else
# other session store for development in webrick/mongrel
# setup cookie based session
ActionController::Base.session = {
:key => '_dd_session',
:secret => '<Your really long random secret key>'
}
end
This will store your rails session in Tomcat's session store exactly as if you were running a Java web framework.Second... Why?
There are a few common solutions starting with the rails default.Cookie Store: This is not very secure, limited in size, and sends a lot of data back and forth to the client. It is strongly recommended to not use this for production systems.
File Store: Stores sessions on the file system. Every cookie access involves file system IO. Does not support clustering by default but can be achieved through a SAN or shared storage.
ActiveRecord: Stores sessions in the database. Slow due to database IO. Natively supports clustering.
Memcached: Stores sessions in Memcached instance. Very popular and works well with clusters. Can run into RAM issues on systems with lots of users. Requires an instance of Memcached running.
Java Servlet Store: Works just like your other Java applications. Java Servers can be configured to cluster sessions. Uses the JSESSIONID cookie or url param (in Tomcat)
Conclusion
This won't be the solution for everyone, but if you're deploying a JRuby on Rails app into an infrastructure based on Java, then it provides a simple and efficient solution.2 Comments
Leave a comment
0 TrackBacks
Listed below are links to blogs that reference this entry: Session Storage in JRuby on Rails.
TrackBack URL for this entry: http://www.nearinfinity.com/mt/mt-tb.cgi/1607



Actually, there's a reason the cookie store is the default. It is as secure as you want it to be, with the default Rails app generation using SHA1 and creating a random secret 30 characters long. It's also the easiest to use in a load-balancing set up as you don't have session affinity to worry about.
There is the size restriction (4k) but if you follow typical Rails conventions and don't bloat your session too much, it works fine.
We recommend the Java servlet session store only in cases where it makes sense, when you have Java and Ruby code both interacting with objects in the servlet session. You more or less say this already but I wanted to point out that the cookie session is still preferred unless your situation warrants.
Finally some good post about it. However, as I'm more familiar with Rails than with Java app containers (like Tomcat), can You guys explain me, what options I have when using JavaServletStore. You mentioned cookie and url params for Tomcat - are there others out-of-the-box implementations which I can use directly from Java?
We do have situation in our project, that we need to store some java and ruby objects in session. I understand that we should be using JavaServletStore, but I'm wondering what options there are for configuring it (on Tomcat 6) and if their all just transparent for Rails app because of using jruby-rack?