Ruby 类变量、rake任务和cron上带有互斥对象的Rails

Ruby 类变量、rake任务和cron上带有互斥对象的Rails,ruby,multithreading,ruby-on-rails-3,Ruby,Multithreading,Ruby On Rails 3,很抱歉问这么大的问题。我对Railsthreads和mutex没有太多经验 我有一个如下的类,不同的控制器使用该类为每个客户获取许可证 每小时都会添加和删除客户及其许可证。api可用于获取所有客户及其许可证 我计划创建一个rake任务来调用update\u set\u customers\u licenses,通过cronjob每小时运行一次 我有以下问题: 1) 即使使用互斥锁,目前也存在潜在的问题,我的rake任务有可能在更新时发生。有没有办法解决这个问题 2) 我下面的设计将json写入一

很抱歉问这么大的问题。我对Rails
threads
mutex
没有太多经验

我有一个如下的类,不同的控制器使用该类为每个客户获取许可证

每小时都会添加和删除客户及其许可证。api可用于获取所有客户及其许可证

我计划创建一个rake任务来调用
update\u set\u customers\u licenses
,通过
cronjob
每小时运行一次

我有以下问题:

1) 即使使用
互斥锁
,目前也存在潜在的问题,我的rake任务有可能在更新时发生。有没有办法解决这个问题

2) 我下面的设计将
json
写入一个文件,这样做是为了安全,因为api不太可靠。正如可以看到的,它并没有读回文件,因此从本质上讲,文件写入是无用的。我试图实现一个文件读取,但与
mutex
rake任务
一起,它变得非常混乱。在这里,任何指针都会有帮助

class Customer
  @@customers_to_licenses_hash = nil
  @@last_updated_at = nil
  @@mutex = Mutex.new

  CUSTOMERS_LICENSES_FILE = "#{Rails.root}/tmp/customers_licenses"

  def self.cached_license_with_customer(customer)
    Rails.cache.fetch('customer') {self.license_with_customer(customer)}
  end

  def self.license_with_customer(customer)
    @@mutex.synchronize do
      license = @@customers_to_licenses_hash[customer]
      if license
        return license
      elsif(@@customers_to_licenses_hash.nil? || Time.now.utc - @@last_updated_at > 1.hours)
        updated = self.update_set_customers_licenses
        return @@customers_to_licenses_hash[customer] if updated
      else
        return nil
      end
    end
  end

  def self.update_set_customers_licenses
    updated = nil
    file_write = File.open(CUSTOMERS_LICENSES_FILE, 'w')
    results = self.get_active_customers_licenses
    if results
      @@customers_to_licenses_hash = results
      file_write.print(results.to_json)
      @@last_updated_at = Time.now.utc
      updated = true
    end
    file_write.close
    updated
  end

  def self.get_active_customers_licenses
    #http get thru api
    #return hash of records
  end
end

我很高兴,每次rails加载时,环境都是“新鲜”的,在实例之间没有“状态”的概念。也就是说,一个ruby实例(对rails的一个请求)中的互斥对另一个ruby实例(对rails的另一个请求,或者在本例中是一个rake任务)没有影响

如果您跟踪数据上游,您会发现可以用于同步它们的每个实例的公共根是数据库。您可以使用或手动在数据库中设置和取消设置标记