DRb troubles, cannot Marshal or proxy objects successfully.

S

sean.swolfe

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top