lib/taskinator/persistence.rb in taskinator-0.0.15 vs lib/taskinator/persistence.rb in taskinator-0.0.16

- old
+ new

@@ -92,17 +92,18 @@ end end # persists the error information def fail(error=nil) - return unless error + return unless error && error.is_a?(Exception) + Taskinator.redis do |conn| conn.hmset( self.key, :error_type, error.class.name, :error_message, error.message, - :error_backtrace, JSON.generate(error.backtrace) + :error_backtrace, JSON.generate(error.backtrace || []) ) end end # retrieves the error type, message and backtrace @@ -180,27 +181,12 @@ @hmset += [attribute, type.name] if type end def visit_args(attribute) values = @instance.send(attribute) - - # special case, convert models to global id's - if values.is_a?(Array) - - values = values.collect {|value| - value.respond_to?(:global_id) ? value.global_id : value - } - - elsif values.is_a?(Hash) - - values.each {|key, value| - values[key] = value.global_id if value.respond_to?(:global_id) - } - - end - - @hmset += [attribute, YAML.dump(values)] + yaml = Taskinator::Persistence.serialize(values) + @hmset += [attribute, yaml] end end class RedisDeserializationVisitor < Taskinator::Visitor::Base @@ -287,34 +273,16 @@ # deserializes the arguments using YAML#load method def visit_args(attribute) yaml = @attribute_values[attribute] if yaml - values = YAML.load(yaml) - - # special case for models, so find model - if values.is_a?(Array) - - values = values.collect {|value| - # is it a global id? - value.respond_to?(:model_id) && value.respond_to?(:find) ? value.find : value - } - - elsif values.is_a?(Hash) - - values.each {|key, value| - # is it a global id? - values[key] = value.find if value.respond_to?(:model_id) && value.respond_to?(:find) - } - - end - + values = Taskinator::Persistence.deserialize(yaml) @instance.instance_variable_set("@#{attribute}", values) end end - private + private # # creates a proxy for the instance which # will only fetch the instance when used # this offers not only an optimization at load @@ -340,19 +308,59 @@ # to keep loading the same objects again. # # E.g. this is useful for tasks which refer to their parent processes # - def initialize(type, uuid, instance_cache) + def initialize(type, uuid, instance_cache={}) @type = type @uuid = uuid @instance_cache = instance_cache end + attr_reader :uuid # shadows the real method, but will be the same! + + # attempts to reload the actual process + def reload + @instance = nil + __getobj__ + @instance ? true : false + end + def __getobj__ # only fetch the object as needed # and memoize for subsequent calls @instance ||= @type.fetch(@uuid, @instance_cache) end end + + class << self + def serialize(values) + # special case, convert models to global id's + if values.is_a?(Array) + values = values.collect {|value| + value.respond_to?(:global_id) ? value.global_id : value + } + elsif values.is_a?(Hash) + values.each {|key, value| + values[key] = value.global_id if value.respond_to?(:global_id) + } + end + YAML.dump(values) + end + + def deserialize(yaml) + values = YAML.load(yaml) + if values.is_a?(Array) + values = values.collect {|value| + (value.respond_to?(:model_id) && value.respond_to?(:find)) ? value.find : value + } + elsif values.is_a?(Hash) + values.each {|key, value| + values[key] = value.find if value.respond_to?(:model_id) && value.respond_to?(:find) + } + end + values + end + end + end end