Forum: Ruby DRb troubles, cannot Marshal or proxy objects successfully.

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.
499f4dccdedd68c1f51ee5a929a0c027?d=identicon&s=25 sean.swolfe@gmail.com (Guest)
on 2006-01-09 10:07
(Received via mailing list)
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
This topic is locked and can not be replied to.