class Taskinator::Persistence::RedisDeserializationVisitor
Public Class Methods
new(key, instance_cache={})
click to toggle source
initialize with the store key for the instance to deserialize
optionally, pass in a hash which is used to cache the deserialized instances for the given key
# File lib/taskinator/persistence.rb, line 464 def initialize(key, instance_cache={}) @key = key @instance_cache = instance_cache # pre-load all the attributes to reduce redis hits Taskinator.redis do |conn| keys, values = conn.multi do conn.hkeys(@key) conn.hvals(@key) end @attribute_values = Hash[keys.collect(&:to_sym).zip(values)] end end
Public Instance Methods
visit()
click to toggle source
the starting point for deserializing the instance
# File lib/taskinator/persistence.rb, line 479 def visit return unless @attribute_values.key?(:type) type = @attribute_values[:type] klass = Kernel.const_get(type) # # NOTE: # using Class#allocate here so that the # instance is created without the need to # call the Class#new method which has constructor # arguments which are unknown at this stage # @instance = klass.allocate @instance.accept(self) @instance end
visit_args(attribute)
click to toggle source
deserializes the arguments using YAML#load method
# File lib/taskinator/persistence.rb, line 557 def visit_args(attribute) yaml = @attribute_values[attribute] if yaml values = Taskinator::Persistence.deserialize(yaml) @instance.instance_variable_set("@#{attribute}", values) end end
visit_attribute(attribute) { |value| ... }
click to toggle source
# File lib/taskinator/persistence.rb, line 520 def visit_attribute(attribute) value = @attribute_values[attribute] if value # converted block given? if block_given? @instance.instance_variable_set("@#{attribute}", yield(value)) else @instance.instance_variable_set("@#{attribute}", value) end end end
visit_attribute_enum(attribute, type)
click to toggle source
NB: assumes the enum type's members have integer values!
# File lib/taskinator/persistence.rb, line 539 def visit_attribute_enum(attribute, type) visit_attribute(attribute) do |value| const_value = type.constants.select {|c| type.const_get(c) == value.to_i }.first const_value ? type.const_get(const_value) : (defined?(type::Default) ? type::Default : nil) end end
visit_attribute_time(attribute)
click to toggle source
# File lib/taskinator/persistence.rb, line 532 def visit_attribute_time(attribute) visit_attribute(attribute) do |value| Time.parse(value) end end
visit_process(attribute)
click to toggle source
# File lib/taskinator/persistence.rb, line 497 def visit_process(attribute) uuid = @attribute_values[attribute] @instance.instance_variable_set("@#{attribute}", lazy_instance_for(Process, uuid)) if uuid end
visit_process_reference(attribute)
click to toggle source
# File lib/taskinator/persistence.rb, line 510 def visit_process_reference(attribute) uuid = @attribute_values[attribute] @instance.instance_variable_set("@#{attribute}", lazy_instance_for(Process, uuid)) if uuid end
visit_task_reference(attribute)
click to toggle source
# File lib/taskinator/persistence.rb, line 515 def visit_task_reference(attribute) uuid = @attribute_values[attribute] @instance.instance_variable_set("@#{attribute}", lazy_instance_for(Task, uuid)) if uuid end
visit_tasks(tasks)
click to toggle source
# File lib/taskinator/persistence.rb, line 502 def visit_tasks(tasks) # tasks are a linked list, so just get the first one Taskinator.redis do |conn| uuid = conn.lindex("#{@key}:tasks", 0) tasks.attach(lazy_instance_for(Task, uuid), conn.get("#{@key}.count").to_i) if uuid end end
visit_type(attribute)
click to toggle source
# File lib/taskinator/persistence.rb, line 548 def visit_type(attribute) value = @attribute_values[attribute] if value type = Kernel.const_get(value) @instance.instance_variable_set("@#{attribute}", type) end end
Private Instance Methods
lazy_instance_for(base, uuid)
click to toggle source
creates a proxy for the instance which will only fetch the instance when used this offers not only an optimization at load time, but also prevents need to load the entire object graph everytime a worker fetches an arbitrary instance to perform it's work
# File lib/taskinator/persistence.rb, line 575 def lazy_instance_for(base, uuid) type = Taskinator.redis do |conn| conn.hget(base.key_for(uuid), :type) end klass = Kernel.const_get(type) LazyLoader.new(klass, uuid, @instance_cache) end