DRb troubles, cannot Marshal or proxy objects successfully


#1

I’ve been trying for hours trying ot get my DRb session store working.
I can get it to work in a gerneralized way, but I need to add some
validation to check the state of the session data, and keep track of
it, in case I need to invalidate the session data, so a user doen’t
track with stale data on a website.

My first tries, I noticed that the objects that were coming in to my
Drb server were not being unmarshalled, This was fine if i just wanted
to store the data, but I needed to see values inside. So I tried
getting marshaling working. First i tried making class stubs for the
classes that were coming over, but I would get :
usr/lib/ruby/1.8/drb/drb.rb:582:in `load’:dump format error (user
class)

So then I tried proxying the code, but the first time it comes across,
I get:
/usr/lib/ruby/1.8/drb/drb.rb:1094: `0x114475a is recycled object’
(RangeError)

I’ve been searching all over the net and have only found some very
vague information.

I hope someone can help me out here…

Here’s my code.
======drb_server.rb============
#!/usr/bin/env ruby -w

This is a session storage daemon, basically just a hash,

which is enabled for DRb access. But it has timestamping,

for expiration and a way for setting if the information is invalid.

require ‘drb/drb’

session_hash = Hash.new
session_hash.instance_eval { @mutex = Mutex.new; @user_hash = Hash.new
}
TIMEOUT = 15 * 60 # 15 minute Timeout

#uncomment these classes if you want to marshal
#class User
#end

#class ActionController
#end

#class ActionController::Flash
#end

#class ActionController::Flash::FlashHash
#end

class <<session_hash

def []=(key, value)
    begin
        if value['user']
            user_id = value['user'][:id]
            if @user_hash[user_id]
                @user_hash[user_id] = (@user_hash[user_id]) << key
            else
                @user_hash[user_id] = [ key ]
            end
        end
    rescue
        #contains an unknown object type
    end
    @mutex.synchronize do
        super(key, [Time.now, value])
        value
    end
end

def [](key)
    instance = nil
    @mutex.synchronize do
        instance = super(key)
    end
    if instance
        # check the time
        last_access = instance[0]
        value = instance[1]
        if(Time.now <= last_access + TIMEOUT)
            #its within the timeout, update the new expiration
                self[key] = value
            return value
        else
            #it out of time, drop the session
            delete(key)
            return nil
        end
    else
        return nil
    end
end

def delete(key)
    @mutex.synchronize do
        super(key)
    end
end

def invalidate_data(user_id)
    if @user_hash
        # get the array of sessions that contain this user
        user_session = nil
        user_sessions = @user_hash[user_id] #get the array of

tracked sessions for this user

        user_sessions.each do |session_id|
            session = self[session_id]
            unless session
                #this session no longer exists, stop tracking the

session
@user_hash[user_id] = user_sessions.delete(session)
return
end
session[‘user_state’] = “INVALID”
self[session_id] = session
end
end
end

end

DRb.start_service(‘druby://127.0.0.1:9192’, session_hash)
DRb.thread.join
======drb_store.rb========

this is a simple CGI Session class that contains a

drb client

require ‘cgi’
require ‘cgi/session’
require ‘drb’

SERVER_URL = ‘druby://localhost:9192’

class CGI #:nodoc:all
class Session
class DRbStore
@@session_data = DRbObject.new(nil, SERVER_URL)

  def initialize(session, option=nil)
    @session_id = session.session_id
  end

  def restore
    @h = @@session_data[@session_id] || {}
  end

  def update
    @h.extend DRbUndumped    #comment this line for Marshaling
    @@session_data[@session_id] = @h
  end

  def close
    update
  end

  def delete
    @@session_data.delete(@session_id)
  end

end

end
end
======/end files/=======

Please, if anyone can help, I’d be most grateful.

Sean