在我的Rails应用程序中,我正在尝试接受我的API调用,并由后台工作人员处理。
我在app / jobs / api_request_job.rb中有以下内容:
class ApiRequestJob
def self.perform(params)
Query.new(params).start
end
end
Query类是执行HTTParty请求的地方(对于具有与parks
方法相同的基本格式的不同查询类型,有许多方法:
require 'ostruct'
class Query
include FourSquare
attr_reader :results,
:first_address,
:second_address,
:queries,
:radius
def initialize(params)
@results = OpenStruct.new
@queries = params["query"]
@first_address = params["first_address"]
@second_address = params["second_address"]
@radius = params["radius"].to_f
end
def start
queries.keys.each do |query|
results[query] = self.send(query)
end
results
end
def parks
category_id = "4bf58dd8d48988d163941735"
first_address_results = FourSquare.send_request(@first_address, radius_to_meters, category_id)["response"]["venues"]
second_address_results = FourSquare.send_request(@second_address, radius_to_meters, category_id)["response"]["venues"]
response = [first_address_results, second_address_results]
end
最后,控制器。在尝试将此操作提供给后台工作人员之前,此行正常运行:@results = Query.new(params).start
class ComparisonsController < ApplicationController
attr_reader :first_address, :second_address
def new
end
def show
@first_address = Address.new(params["first_address"])
@second_address = Address.new(params["second_address"])
if @first_address.invalid?
flash[:notice] = @first_address.errors.full_messages
redirect_to :back
elsif Query.new(params).queries.nil?
flash[:notice] = "You must choose at least one criteria for your comparison."
redirect_to comparisons_new_path(request.params)
else
@queries = params["query"].keys
@results = Resque.enqueue(ApiRequestJob, params) # <-- this is where I'm stuck
end
end
end
我正在运行redis,安装了resque,并且正在运行任务/启动工作人员。 @results返回的当前值是true
,而不是我需要返回的结果的哈希值。有没有办法让Resque作业的结果保持不变并返回数据而不是true
?关于如何让后台工作人员返回我的常规api调用返回的相同类型的数据,我错过了什么?
非常感谢提前!
答案 0 :(得分:1)
您收到的true
表示该作业已安排成功排队。工作人员会将其拾取并在后台异步运行,这意味着,不会与排队的线程同时运行。因此,无法从作业中检索返回的值。
如果您需要该进程的值,则必须在没有worker的情况下从控制器运行它。此外,你不会从另一个过程推动工作中获得任何收益,因为网络流程必须等待响应,然后继续前进。
如果您需要立即返回值,并且出于性能原因这样做,那么您可以查看其他形式的并发,例如让另一个thread执行请求,然后只在需要时抓取结果在视图上:
class AsyncValue
def initialize(&block)
@thr = Thread.new(&block)
end
def value
@thr.join
end
end
在控制器上
@results = AsyncValue.new { Query.new(params).start }
并在视图上
<%= @results.value.each .... %>
但是您仍然需要解决错误处理问题,这可能会非常复杂,但是可行。
就个人而言,我只是提出了请求,但您比我更了解您的域名。