2014-12-02 2 views
0

В моем приложении Rails я пытаюсь использовать свои рабочие API-вызовы и обрабатывать их фоновые работники.Сохранять результаты работы с помощью Resque/Rails

У меня есть следующие в приложение/Работа/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

Эй вы могли решить вашу проблему? – rafb3

ответ

1

true Вы получаете сообщение, что задача была запланирована успешно завершена. Работник подберет его и запустит на асинхронном фоне, а это значит, что в то же время, что и поток, который его выставил в очередь. Таким образом, нет способа получить возвращаемое значение из задания.

Если вам нужно значение из этого процесса, вы должны запустить его с контроллера без рабочего. Кроме того, вы ничего не выиграете, просто нажимая работу, которую должен выполнить другой процесс, поскольку веб-процесс должен будет ждать ответа, а затем продолжать идти в любом случае.

Если вам нужно это возвращенное значение прямо сейчас и делаете это по соображениям производительности, вы можете посмотреть на другие формы параллелизма, например, сделать еще один 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 .... %> 

, но вам все равно придется работать с обработкой ошибок, которая может стать довольно сложной, но выполнимой.

Лично я просто сделал запрос на месте, но вы знаете свой домен лучше меня.

+0

Спасибо за ответ! Да, я поговорил с некоторыми другими людьми об этом и понял, что фоновые работники не собираются помогать мне в производительности, так как моя страница опиралась на возвращаемое значение. Мне нравится предложение потоковой передачи, но думаю, что в конечном итоге я попытаюсь сократить свою зависимость от ответа API, соскабливая и просто сохраняя результаты, которые я поддерживаю в базе данных. – Jim

Смежные вопросы