Forum: Ruby on Rails memcache, sessions, fragments, oh my!

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Philip H. (Guest)
on 2006-04-20 04:29
(Received via mailing list)
Hi all -

I am trying to get rails to use memcache for sessions and fragment
caching.  I'd also like to use the same connection for general caching
of
this and that.

I'm following the instructions here:
http://wiki.rubyonrails.com/rails/pages/HowtoChang...

and hitting a brick wall.

I'm using the new memcache-client since from what I've read it's faster,
but it's implementation is different enough that I can't figure out how
to
make it work with:

 	config.action_controller.session_store = :mem_cache_store
 	config.action_controller.fragment_cache_store = :mem_cache_store

I've got this in environment.rb as well:

 	MEMCACHE_OPTIONS = {
 	  :compression => false,
 	  :debug => false,
 	  :namespace => "#{RAILS_ENV}",
 	  :readonly => false,
 	  :urlencode => false
 	}
 	MEMCACHE_SERVERS = [ '192.168.1.20:11211' ]

and if I leave everything else out and run script/console I can use
those
defines to create a Memcache object, but I have no idea how to get that
same instance to be used for session_store and fragment_cache_store.

Anyone want to share their config?  Or tell me to go back and use
RubyMemcache instead?

Thanks!

-philip
Jonathan W. (Guest)
on 2006-04-20 21:36
(Received via mailing list)
> Anyone want to share their config?  Or tell me to go back and use
> RubyMemcache instead?
>

I described my config here

http://blog.innerewut.de/articles/2006/02/09/time-...

I use the newer memcache-client for sessions and fragments and had no
problems so far.

Jonathan
Adrian M. (Guest)
on 2006-04-22 01:20
(Received via mailing list)
Jonathan,

Thanks for the info. I had a longer reimplementation of the
MemCacheStore
just because I don't know Ruby enough (namespaces and all that). I can't
seem to make memcache work for my session, though. I have set your code
in
environments/development.rb (want to test if before moving to
production). I
keep getting errors about user class/module not found. Any ideas why?

Thanks,


Adrian M.
Philip H. (Guest)
on 2006-04-22 01:26
(Received via mailing list)
> Jonathan,
>
> Thanks for the info. I had a longer reimplementation of the MemCacheStore
> just because I don't know Ruby enough (namespaces and all that). I can't
> seem to make memcache work for my session, though. I have set your code in
> environments/development.rb (want to test if before moving to production). I
> keep getting errors about user class/module not found. Any ideas why?
>
> Thanks,

Here's what my environment.rb looks like (based off of Jonathan's blog
entry).  Hope it helps.

#
# MemCache
#
require 'memcache'
require 'memcache_util'

MEMCACHE_SERVERS = '127.0.0.1:11211' unless defined?(MEMCACHE_SERVERS)

CACHE = MemCache.new :c_threshold => 10_000,
                                          :compression => false,
                                          :debug => false,
                                          :namespace => "#{RAILS_ENV}",
                                          :readonly => false,
                                          :urlencode => false
CACHE.servers = MEMCACHE_SERVERS

#
# Use our memcache object to store sessions
#
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(
         :database_manager => CGI::Session::MemCacheStore,
         :cache => CACHE
)
Jonathan W. (Guest)
on 2006-04-22 02:16
(Received via mailing list)
Adrian M. wrote:
> Jonathan,
>
> Thanks for the info. I had a longer reimplementation of the
> MemCacheStore just because I don't know Ruby enough (namespaces and all
> that). I can't seem to make memcache work for my session, though. I have
> set your code in environments/development.rb (want to test if before
> moving to production).

You can always test production with

# ruby script/server webrick -e production

> I keep getting errors about user class/module not
> found. Any ideas why?

Can you post your exact errors?


>
> Thanks,
>
>
> Adrian M.

Jonathan
Adrian M. (Guest)
on 2006-04-22 02:34
(Received via mailing list)
Philip,

Thanks for the info. Question, are you doing that before or after the
whole
"Rails::Initializer.run do |config|" code?

Thanks,


Adrian M.
Adrian M. (Guest)
on 2006-04-22 02:50
(Received via mailing list)
Here is the error log after I login. BTW, I'm keeping the user in the
session and not just the user id:

Processing LoginController#login (for 123.456.789.123 at 2006-04-21
17:37:42) [POST]
  Session ID: d6e08ee536af1abb395dbb183820fa11
  Parameters: {"user"=>{"username"=>"admin", "password"=>"xxxxxx"},
"x"=>"53", "y"=>"11", "action"=>"login", "controller"=>"login"}
  User Columns (0.000223)   SHOW FIELDS FROM users
  User Load (0.000320)   SELECT * FROM users WHERE (username = 'admin'
and
password = 'xxxxxx') LIMIT 1
  Event Columns (0.000179)   SHOW FIELDS FROM events
  SQL (0.000060)   BEGIN
  SQL (0.000266)   INSERT INTO events (`created_on`, `name`, `row_id`,
`action`, `description`, `auth_id`, `created`) VALUES('2006-04-21
17:37:42',
'users', 1, 'login', '123.456.789.123', 9999,
'2006-04-21T17:37:42-0500')
  SQL (0.000042)   COMMIT
Succesful login, adding user to session
  Region Load (0.000281)   SELECT * FROM regions WHERE (regions.id = 13)
LIMIT 1
  UserAddress Columns (0.000232)   SHOW FIELDS FROM addresses
  UserAddress Load (0.000404)   SELECT * FROM addresses WHERE (
addresses.row_id = 1) AND ( (addresses.`type` = 'UserAddress' ) ) LIMIT
1
Logged in User nil
Redirected to http://test.domain.com/InfoCenter
Completed in 0.03118 (32 reqs/sec) | DB: 0.00201 (6%) | 302 Found [
http://test.domain.com/]
  Join Table Columns (0.000182)   SHOW FIELDS FROM groups_users
  Group Load (0.000599)   SELECT * FROM groups INNER JOIN groups_users
ON
groups.id = groups_users.group_id WHERE (groups_users.user_id = 1 )
ORDER BY
name
  Group Columns (0.000129)   SHOW FIELDS FROM groups
  Region Columns (0.000143)   SHOW FIELDS FROM regions
  Preference Load (0.000457)   SELECT * FROM preferences WHERE (
preferences.user_id = 1) ORDER BY `group`, name
  Preference Columns (0.000159)   SHOW FIELDS FROM preferences
undefined class/module User
/usr/local/lib/ruby/gems/1.8/gems/memcache-client-1.0.3/lib/memcache.rb:128:in
`get'
/usr/local/lib/ruby/1.8/thread.rb:135:in `synchronize'
/usr/local/lib/ruby/gems/1.8/gems/memcache-client-1.0.3/lib/memcache.rb:98:in
`get'
/usr/local/lib/ruby/gems/1.8/gems/memcache-client-1.0.3/lib/memcache.rb:191:in
`[]'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session/mem_cache_store.rb:67:in
`restore'
/usr/local/lib/ruby/1.8/cgi/session.rb:305:in `[]'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/cgi_process.rb:113:in
`session'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/cgi_process.rb:141:in
`stale_session_check!'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/cgi_process.rb:107:in
`session'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:887:in
`assign_shortcuts_without_flash'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/flash.rb:141:in
`assign_shortcuts'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:375:in
`process_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/filters.rb:377:in
`process_without_session_management_support'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/session_management.rb:117:in
`process'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/dispatcher.rb:38:in
`dispatch'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/fcgi_handler.rb:150:in
`process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/fcgi_handler.rb:54:in
`process!'
/usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:600:in `each_cgi'
/usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:597:in `each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/fcgi_handler.rb:53:in
`process!'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/fcgi_handler.rb:23:in
`process!'
/home/iflo/domains/infocenter.iflo.com/current/public/dispatch.fcgi:24

It seems to me that the session does not know about the user
class/model. If
I switch back to a PSTORE I don't have any problems. Very weird. Here is
my
environment.rb:

# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '1.1.2'

# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')

#
====================================================================================================
# Memcached
#
----------------------------------------------------------------------------------------------------
MEMCACHE_SERVERS = '127.0.0.1:11211' unless defined?(MEMCACHE_SERVERS)
CACHE = MemCache.new :c_threshold => 10_000,
                     :compression => false,
                     :debug => false,
                     :namespace => "domain",
                     :readonly => false,
                     :urlencode => false
CACHE.servers = MEMCACHE_SERVERS

#
====================================================================================================
# Initializer
#
----------------------------------------------------------------------------------------------------
Rails::Initializer.run do |config|
  config.frameworks -= [ :action_web_service ]
end

#
====================================================================================================
# Fragments
#
----------------------------------------------------------------------------------------------------
class ActionController::Caching::Fragments::MemCacheStore
  def data=(cache)
    @data = cache
  end
  def write(name, value, options=nil)
    if name =~ %r{^Min30}
            @data.set(name, value, 30.minutes)
    elsif name =~ %r{^Min60}
            @data.set(name, value, 60.minutes)
    elsif name =~ %r{^Min90}
            @data.set(name, value, 90.minutes)
    else
            @data.set(name, value, 120.minutes)
    end
  end
end
ActionController::Base.fragment_cache_store = :mem_cache_store ,{}
ActionController::Base.fragment_cache_store.data = CACHE

#
====================================================================================================
# Session
#
----------------------------------------------------------------------------------------------------
session_type = "memcached"
session_options                     = Hash.new
if session_type == "pstore"
    session_options[:database_manager] = CGI::Session::PStore
    session_options[:prefix]           = 'dom_'
    session_options[:tmpdir]           = '/home/domain/pstore'
else
    session_options[:database_manager] = CGI::Session::MemCacheStore
    session_options[:cache]            = CACHE
end
session_options[:session_domain]   = '.domain.com'
session_options[:session_key]      = 'domain'
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(session_options)


Hope this helps in figuring this out because I keep banging my head
against
it. If you see anything that could help me please let me know.

Thanks again,


Adrian M.
Philip H. (Guest)
on 2006-04-22 03:17
(Received via mailing list)
>
> Thanks for the info. Question, are you doing that before or after the whole
> "Rails::Initializer.run do |config|" code?


After.  The rest of my environment.rb file is stock.
Jonathan W. (Guest)
on 2006-04-22 03:17
(Received via mailing list)
do you have

class ApplicationController < ActionController::Base
   model :user
end

In the application controller?


Jonathan
Adrian M. (Guest)
on 2006-04-22 03:45
(Received via mailing list)
Jonathan,

I don't and for some reason I  can quite remember I thought it wasn't
needed
anymore. The funny thing is that if I switch to PStore (session_type =
"pstore")  then I don't have any problems with classes not loaded. I
will
try adding that although there are a lot of models that I save in the
session depending of what the suer does on the site. Do you kow if there
is
something in the PStore manager that loads on demmand the classes the
current session requires?

Thanks,


Adrian M.
Adrian M. (Guest)
on 2006-04-22 03:54
(Received via mailing list)
Jonathan,

Sorry, I was giving you the wrong information. I was doing "require
/path/to/models/user" instead of "model :user". I don't see a major
difference but I will try it anyway and let you know.

Thanks,

Adrian M.
Adrian M. (Guest)
on 2006-04-22 04:00
(Received via mailing list)
Jonathan,

Looks like model :model_name has been deprecated because it complaints
that
the method does not exist and I can't find it in the docs.

Sincerely,


Adrian M.
Jonathan W. (Guest)
on 2006-04-22 17:49
(Received via mailing list)
Adrian M. wrote:
> Jonathan,
>
> Looks like model :model_name has been deprecated because it complaints
> that the method does not exist and I can't find it in the docs.

I use

model :user

with Rails 1.1.2 and have no problems so far.


Jonathan
This topic is locked and can not be replied to.