module Mongoid::DistributeTree::ClassMethods

Constants

DeleteCallback

Public Instance Methods

perform(_uuid, _distribute_url, is_with_children = false) click to toggle source
# File lib/distribute_tree.rb, line 51
def perform _uuid, _distribute_url, is_with_children = false
  klass = self
  # 兼容 被删除 或者 软删除
  item = (klass.respond_to?(:unscoped) ? klass.unscoped : klass).uuid(_uuid)
  is_deleted = item.nil? || (item.respond_to?(:deleted?) && item.deleted?)

  # sync data structure
  payload = {
    model_name: klass.name,
    model: is_deleted ? {uuid: _uuid, delete: true} : item.as_json
  }

  # sync json
  # RestClient.put "#{_distribute_url}/upload/warpgate", {:payload => payload}
  # 会导致把app_versions解释为单个对象的Hash。
  Rails.logger.info "[DistributeTree] begin sync #{klass}[#{item.uuid}] json at #{Time.now}"
  RestClient.put "#{_distribute_url}/upload/warpgate.json", {:payload => payload}.to_json,  {:content_type => :json}
  Rails.logger.info "[DistributeTree] end   sync #{klass}[#{item.uuid}] json at #{Time.now}"

  # 不处理已经被删除的
  (DeleteCallback.call(klass.name, _uuid, _distribute_url); return false) if is_deleted

  paperclip_items = [item]
  # 获取embeds_many里的含有paperclip对象,目前只支持一级
  klass.relations.each do |k, v|
    next if not v.macro == :embeds_many
    paperclip_items += item.send(k).to_a
  end
  # 在paperclip文件对象选择上使用方法反射
  paperclip_regexp = /_([a-z_]+)_post_process_callbacks/
  paperclip_items.each do |paperclip_item|
    next if not paperclip_item.methods.include?(:upload_path)
    paperclip_method = paperclip_item.methods.detect {|m| m.match(paperclip_regexp) }.to_s.match(paperclip_regexp)[1]
    file_path = paperclip_item.send(paperclip_method).path
    next if not File.exists? file_path
    Rails.logger.info "[DistributeTree] begin sync #{klass}[#{item.uuid}] file at #{Time.now}"
    RestClient.put "#{_distribute_url}#{paperclip_item.upload_path}", :file => File.new(file_path, 'rb')
    Rails.logger.info "[DistributeTree] end   sync #{klass}[#{item.uuid}] file at #{Time.now}"
  end

  # distribute children
  item.distribute_children.each do |relation|
    item.send(relation).to_a.each do |item2|
      Resque.enqueue item2.class, item2.uuid, _distribute_url, is_with_children
    end
  end if is_with_children.to_s == 'true' # 兼容resque可能不能反序列化True/False

  DeleteCallback.call(klass.name, _uuid, _distribute_url)
end