I''m sure many of you have hit that annoying SessionRestoreError: http://wiki.rubyonrails.com/rails/show/HowtoAvoidSessionRestoreError (and http://api.rubyonrails.com/classes/ActionController/Base.html in Sessions section) The only good solution I''ve found for the problem (besides not storing objects in @session) is something like this: @session[''stored_object''] = Marshal.dump(my_object) Then, to get it back: my_object = Marshal.load(@session[''stored_object'']) It really makes my life easier, so I thought I''d share it, and see if there''s any feedback about the idea. There''s a performance hit, I suppose, but it only affects the controllers that do the marshaling. I tend to use it in low traffic controllers (like for admin pages), so the performance isn''t an issue for me. Another problem is that the code is a little more verbose, so I was wondering if it would be nice to have it built into rails. Maybe controllers that want it would look like: class MyController < ApplicationController marshal_session_objects model :my_class def index @session[''my_class''] = MyClass.new end end I don''t know if this would be useful, but I''d be happy to start working on a patch if it is.. Thanks, Zach
On Wed, 18 May 2005, Zach Thompson wrote:> I''m sure many of you have hit that annoying SessionRestoreError: > > http://wiki.rubyonrails.com/rails/show/HowtoAvoidSessionRestoreError > (and http://api.rubyonrails.com/classes/ActionController/Base.html in > Sessions section) > > The only good solution I''ve found for the problem (besides not storing > objects in @session) is something like this: > > @session[''stored_object''] = Marshal.dump(my_object) > > Then, to get it back: > > my_object = Marshal.load(@session[''stored_object'']) > > It really makes my life easier, so I thought I''d share it, and see if there''s > any feedback about the idea. There''s a performance hit, I suppose, but it > only affects the controllers that do the marshaling. I tend to use it in low > traffic controllers (like for admin pages), so the performance isn''t an issue > for me. > > Another problem is that the code is a little more verbose, so I was wondering > if it would be nice to have it built into rails. Maybe controllers that want > it would look like: > > class MyController < ApplicationController > marshal_session_objects > model :my_class > def index > @session[''my_class''] = MyClass.new > end > end > > I don''t know if this would be useful, but I''d be happy to start working on a > patch if it is.. > > Thanks, > Zachi wrote the pstore backend to CGI::Session and this is exactly what it does - only under flock/transaction control too. i suspect there is a way to select the cgi database manage under rails but have been too far from html-land to recall. if you look at the source of cgi/session/pstore.rb under the lib directory of the ruby dist you''ll see this already implemented as a cgi session manager. hopefully this points you in the right direction - i''m slammed for the next week or so and can''t look further... kind regards. -a -- ==============================================================================| email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | My religion is very simple. My religion is kindness. | --Tenzin Gyatso ===============================================================================
I think I''m of the opinion that marshalling the session objects should happen ''out of the box'' as the session simply fails if they are not marshalled/restored -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Zach Thompson Sent: Thursday, 19 May 2005 12:21 PM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: [Rails] marshal session objects? I''m sure many of you have hit that annoying SessionRestoreError: http://wiki.rubyonrails.com/rails/show/HowtoAvoidSessionRestoreError (and http://api.rubyonrails.com/classes/ActionController/Base.html in Sessions section) The only good solution I''ve found for the problem (besides not storing objects in @session) is something like this: @session[''stored_object''] = Marshal.dump(my_object) Then, to get it back: my_object = Marshal.load(@session[''stored_object'']) It really makes my life easier, so I thought I''d share it, and see if there''s any feedback about the idea. There''s a performance hit, I suppose, but it only affects the controllers that do the marshaling. I tend to use it in low traffic controllers (like for admin pages), so the performance isn''t an issue for me. Another problem is that the code is a little more verbose, so I was wondering if it would be nice to have it built into rails. Maybe controllers that want it would look like: class MyController < ApplicationController marshal_session_objects model :my_class def index @session[''my_class''] = MyClass.new end end I don''t know if this would be useful, but I''d be happy to start working on a patch if it is.. Thanks, Zach _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On May 18, 2005, at 9:22 PM, Ara.T.Howard wrote:> i wrote the pstore backend to CGI::Session and this is exactly what it > does - > only under flock/transaction control too. i suspect there is a way to > select > the cgi database manage under rails but have been too far from > html-land to > recall. if you look at the source of cgi/session/pstore.rb under the > lib > directory of the ruby dist you''ll see this already implemented as a cgi > session manager.Thanks for pointing that out - it''s nice to see what''s going on under the hood of session management. You can change the storage manager with this in environment.rb: ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(: database_manager => CGI::Session::PStore) I looked at the rails source, though, and it''s already using PStore as the default storage manager... Zach
On Thu, 19 May 2005, Zach Thompson wrote:> On May 18, 2005, at 9:22 PM, Ara.T.Howard wrote: > >> i wrote the pstore backend to CGI::Session and this is exactly what it does >> - >> only under flock/transaction control too. i suspect there is a way to >> select >> the cgi database manage under rails but have been too far from html-land to >> recall. if you look at the source of cgi/session/pstore.rb under the lib >> directory of the ruby dist you''ll see this already implemented as a cgi >> session manager. > > Thanks for pointing that out - it''s nice to see what''s going on under the > hood of session management. You can change the storage manager with this in > environment.rb: > > ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(: > database_manager => CGI::Session::PStore) > > I looked at the rails source, though, and it''s already using PStore as the > default storage manager... > > Zachthat''s what i thought too - but you weren''t able to store arbitrary objects though right? the code you should would have double marshal''d everything ;-) weird no? -a -- ==============================================================================| email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | My religion is very simple. My religion is kindness. | --Tenzin Gyatso ===============================================================================
On May 19, 2005, at 2:56 PM, Ara.T.Howard wrote:> On Thu, 19 May 2005, Zach Thompson wrote: > >> On May 18, 2005, at 9:22 PM, Ara.T.Howard wrote: >> >>> i wrote the pstore backend to CGI::Session and this is exactly what >>> it does - >>> only under flock/transaction control too. i suspect there is a way >>> to select >>> the cgi database manage under rails but have been too far from >>> html-land to >>> recall. if you look at the source of cgi/session/pstore.rb under >>> the lib >>> directory of the ruby dist you''ll see this already implemented as a >>> cgi >>> session manager. >> >> Thanks for pointing that out - it''s nice to see what''s going on under >> the hood of session management. You can change the storage manager >> with this in environment.rb: >> >> ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(: >> database_manager => CGI::Session::PStore) >> >> I looked at the rails source, though, and it''s already using PStore >> as the default storage manager... >> >> Zach > > that''s what i thought too - but you weren''t able to store arbitrary > objects > though right? the code you should would have double marshal''d > everything ;-) > > weird no?It''s always fun making computers do things like that... :) I think what I''m talking about would actually need to work independently of whatever storage manager is being used for the session. The problem occurs when there are two controllers, and the first stores an object in @session. If the second controller doesn''t have the class definition for that object, then you get a Session Restore Error. So I want to make it so that objects stay marshaled until the moment they are accessed - so the controller without the class definition would still work (since the marshaled object is just a String in @session). Zach
On May 18, 2005, at 7:20 PM, Zach Thompson wrote:> I''m sure many of you have hit that annoying SessionRestoreError: > > http://wiki.rubyonrails.com/rails/show/HowtoAvoidSessionRestoreError > (and http://api.rubyonrails.com/classes/ActionController/Base.html > in Sessions section) > > The only good solution I''ve found for the problem (besides not storing > objects in @session) is something like this: > > @session[''stored_object''] = Marshal.dump(my_object) > > Then, to get it back: > > my_object = Marshal.load(@session[''stored_object'']) >Ok - here''s a start.. You can stick this code in environment.rb and not have to worry about every controller having to require every class that is stored in @session. The marshal occurs only when values in @session are accessed, so each controller can just require its own class definitions. It kind of seems like a hack, but also seems to work: class CGI class Session def [](key) unless @data @data = @dbman.restore end unless @used_data @used_data = {} end if @used_data[key] return @used_data[key] else val = @data[key] if val restored_val = Marshal.load(val) @used_data[key] = restored_val return restored_val end end end def []=(key, val) unless @write_lock @write_lock = true end unless @data @data = @dbman.restore end unless @used_data @used_data = {} end @used_data[key] = val end def update put_used_data_back @dbman.update end def close put_used_data_back @dbman.update @dbprot.clear end private def put_used_data_back @used_data && @used_data.each_pair do |key, val| @data[key] = Marshal.dump(val) end end end end Thanks for any feedback, Zach