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



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

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



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

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



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

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



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

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!



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

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



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

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

#visit_process(attribute) ⇒ Object



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

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



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

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



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

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



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

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



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

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