[Borges-users] suggestion: snapshots without weakrefs

Слепнев Владимир slepnev_v at rambler.ru
Fri May 14 06:38:17 EDT 2004


Hi,

because weakrefs+continuations turned out so buggy (and ignored by 
ruby-core), I designed a way to snapshot stuff without weakrefs. The 
idea is to keep an anonymous module for each session, and use 
ObjectSpace.each_object(mod) to create snapshots. The snapshots of 
objects don't keep their class - just their instance variables, so 
snapshots aren't eligible for snapshotting again. I've unit-tested the 
stuff a bit (though not with Borges yet), and it seems to work.

How we can use this in Borges: the session should have an accessor for 
'backtrack'. Then, if we want to mark an object as backtrackable:

def MyClass
   include session.backtrack
   ....
end

or 'obj.extend session.backtrack'. The implementation of StateHolder 
is likewise straightforward - it is just an object which includes 
session.backtrack.


The session 'backtrack' variable is a module, created like this:

@backtrack = Module.new {include BacktrackMixin }


Snapshots are made like this:
snap = Snapshot.new(session.backtrack)

and restored like this:
snap.restore


There is no need for a StateRegistry - just keep an LRU cache of 
snapshots. 


Here's the source, it's not optimal yet, much room for improvement:


module BacktrackMixin

	def shallow_copy
		copy_instance_variables(self,Object.new)
	end

	def restore_from(copy)
		copy_instance_variables(copy,self)
	end

	private; def copy_instance_variables(src,dest)
		src.instance_variables.each do |name|
			dest.instance_variable_set(name, src.instance_variable_get(name))
		end
		return dest
	end

end

class Snapshot

	def initialize(mod)
		@snap = {}
		ObjectSpace.each_object(mod) {|obj|	@snap[obj] = obj.shallow_copy}
	end

	def restore
		@snap.each {|k,v| k.restore_from v}
	end

	def size; @snap.size end

end


What do you think? 

Vladimir Slepnev


More information about the Borges-users mailing list