Class: Taskinator::Persistence::RedisDeserializationVisitor

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

Instance Method Summary collapse

Methods inherited from Visitor::Base

#task_count

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



506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'lib/taskinator/persistence.rb', line 506

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 |transaction|
      transaction.hkeys(@key)
      transaction.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



521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/taskinator/persistence.rb', line 521

def visit
  return unless @attribute_values.key?(:type)

  type = @attribute_values[:type]
  klass = Kernel.const_get(type) rescue UnknownType.new(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



601
602
603
604
605
606
607
# File 'lib/taskinator/persistence.rb', line 601

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



562
563
564
565
566
567
568
569
570
571
572
# File 'lib/taskinator/persistence.rb', line 562

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

NB: assumes the enum type’s members have integer values!



581
582
583
584
585
586
587
588
589
590
# File 'lib/taskinator/persistence.rb', line 581

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
    if const_value
      type.const_get(const_value)
    else
      defined?(type::Default) ? type::Default : nil
    end
  end
end

#visit_attribute_time(attribute) ⇒ Object



574
575
576
577
578
# File 'lib/taskinator/persistence.rb', line 574

def visit_attribute_time(attribute)
  visit_attribute(attribute) do |value|
    Time.parse(value)
  end
end

#visit_process(attribute) ⇒ Object



539
540
541
542
# File 'lib/taskinator/persistence.rb', line 539

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



552
553
554
555
# File 'lib/taskinator/persistence.rb', line 552

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



557
558
559
560
# File 'lib/taskinator/persistence.rb', line 557

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



544
545
546
547
548
549
550
# File 'lib/taskinator/persistence.rb', line 544

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



592
593
594
595
596
597
598
# File 'lib/taskinator/persistence.rb', line 592

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