Class: Taskinator::Persistence::RedisDeserializationVisitor

Inherits:
Visitor::Base
  • Object
show all
Defined in:
lib/taskinator/persistence.rb

Instance Method Summary collapse

Constructor Details

#initialize(key, instance_cache = {}) ⇒ RedisDeserializationVisitor

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



219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/taskinator/persistence.rb', line 219

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

Instance Method Details

#visitObject

the starting point for deserializing the instance



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/taskinator/persistence.rb', line 234

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) ⇒ Object

deserializes the arguments using YAML#load method



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/taskinator/persistence.rb', line 289

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

    @instance.instance_variable_set("@#{attribute}", values)
  end
end

#visit_attribute(attribute) ⇒ Object



275
276
277
278
# File 'lib/taskinator/persistence.rb', line 275

def visit_attribute(attribute)
  value = @attribute_values[attribute]
  @instance.instance_variable_set("@#{attribute}", value) if value
end

#visit_process(attribute) ⇒ Object



252
253
254
255
# File 'lib/taskinator/persistence.rb', line 252

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) ⇒ Object



265
266
267
268
# File 'lib/taskinator/persistence.rb', line 265

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) ⇒ Object



270
271
272
273
# File 'lib/taskinator/persistence.rb', line 270

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) ⇒ Object



257
258
259
260
261
262
263
# File 'lib/taskinator/persistence.rb', line 257

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 << lazy_instance_for(Task, uuid) if uuid
  end
end

#visit_type(attribute) ⇒ Object



280
281
282
283
284
285
286
# File 'lib/taskinator/persistence.rb', line 280

def visit_type(attribute)
  value = @attribute_values[attribute]
  if value
    type = Kernel.const_get(value)
    @instance.instance_variable_set("@#{attribute}", type)
  end
end