目前我正在构建一个应用程序,允许用户对产品和管理员进行出价以批准它们。 “交易”本身发生在申请范围之外。目前,用户在交易/新页面上查看资产的价格,并通过提交表单提交出价。管理员点击按钮批准出价。
class TransactionsController < ApplicationController
before_action :get_price
def new
@price = get_price
@tansaction = Transaction.new
end
###
def get_price
@price = <<Some External Query>>
end
def approve
t = Transaction.find(params[:id])
t.status = "Approved"
t.update!
end
显然这并不理想。每次用户想要提交出价时,我都不想查询API。理想情况下,我可以在后台每隔5-10秒查询一次这个API并以这种方式使用价格。我已经研究了几种运行后台作业的技术,包括delayed_job,sidekiq和resque。例如在sidekiq我可以运行这样的东西:
#app/workers/price_worker.rb
class PriceWorker
include Sidekiq::Worker
def perform(*args)
get_price
end
def get_price
@price = <<Some External Query>>
end
end
#config/initializers/sidekiq.rb
schedule_file = "config/schedule.yml"
if File.exists?(schedule_file) && Sidekiq.server?
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end
#config/schedule.yml
my_price_job:
cron: "*/10 * * * * * "
class: "PriceWorker"
该代码运行。问题是我对如何处理价格变量并将其从工人传递给用户感到很遗憾。我观看过sidekiq和resque的Railscasts剧集。我编写了后台工作人员和排队并正常运行的作业,但我无法弄清楚如何将它们应用到我的应用程序中。这是我第一次处理后台工作,所以我有很多东西需要学习。我花了一些时间来研究这个问题,似乎更多后台作业用于更长时间运行的任务,例如更新数据库索引而不是不断重复的作业(比如每5秒一次API请求)。
总而言之,运行不断重复的任务(例如在Rails中查询外部API)的正确技术是什么?任何有关如何正确执行此操作的反馈将不胜感激!谢谢。
答案 0 :(得分:0)
我想在这种情况下你应该使用rails cache。把这样的东西放在你的控制器中:
@price = Rails.cache.fetch('price') do
<<Some external query>>
end
您还可以通过设置expires_in
参数来配置缓存过期日期,有关详细信息,请参阅https://apidock.com/rails/ActiveSupport/Cache/Store/fetch。
关于使用后台作业来更新您的&#34;价格&#34;值,你需要存储检索到的数据(使用某种数据库)并在你的控制器中获取它。
答案 1 :(得分:0)
这不是后台工作的工作方式。你是对的,你有很多阅读要做。考虑运行像Sidekiq这样的异步作业处理器作为运行完全独立的应用程序。它与您的Rails应用程序共享相同的代码库,但它完全单独运行 。如果您希望这两个独立的应用程序相互通信,那么您必须设计和编写该代码。
例如,我将使用reader和writer方法定义缓存,然后在必要时填充缓存:
此后,Sidekiq将填充缓存:
继续上述第3步:
当下一个客户端加载产品“foo”时,Rails将读取Sidekiq更新(或未更新)的缓存。
对于这种类型的系统,缓存必须是某种外部存储,如关系数据库(MySQL,Postgres,Sqlite)或NoSQL数据库(Redis,memcache)。您不能使用内部Rails缓存,因为Rails缓存仅存在于Rails应用程序的内存空间内,并且Sidekiq 不可读。 (因为Sidekiq是一个完全独立的应用程序)