Лучший способ получить результаты Rails ActiveJob для возврата в виде JSON в контроллере? - PullRequest
0 голосов
/ 26 августа 2018

Я создаю веб-сервис, который принимает строку, анализирует ее и возвращает как JSON.В моем контроллере я вызываю ActiveJob для запуска службы для анализа данных.Я хотел бы вернуть результаты ActiveJob обратно на мой контроллер, чтобы вернуть его как JSON, и я не уверен, как это сделать.Какой самый простой способ сделать это?

class GeocoderService
  require 'ruby_postal/parser'

  def initialize(address)
    @address = address
  end

  def parse_address
    address_group = {}
    result = Postal::Parser.parse_address(@address)
    result.each do |r|
      address_group[r.values[0]] = r.values[1]
    end
    address_group
  end

class ParseAddressJob < ApplicationJob
  queue_as :default

  def perform(address)
    geo = GeocoderService.new(address)
    result = geo.parse_address
  end

end

class LocationsController < ApplicationController



def create
    if geo_params[:address]
      ParseAddressJob.perform_later(geo_params[:address])
      render json: result
    else
      render json: { error: "Invalid address"}, status: 400
    end
  end

  private

  def geo_params
    params.require(:geo).permit(:address)
  end
end

1 Ответ

0 голосов
/ 26 августа 2018

ActiveJob используется для создания задач, которые выполняются в фоновом режиме и асинхронно из потока запросов / ответов HTTP.Контроллер передает задачу ActiveJob, затем контроллер возвращается, пока задание выполняется в будущем.Если вам нужен вывод из задания немедленно, потому что это что-то, что нужно пользователю, то вам не следует использовать задание - вы просто должны вызывать код, вызываемый заданием напрямую, и блокировать, пока код не будет завершен, чтобы вы могли получить вывод.

def create
  if geo_params[:address]
    geo = GeocoderService.new(geo_params[:address])
    result = geo.parse_address
    render json: result
  else
    render json: { error: "Invalid address"}, status: 400
  end
end

Если вы действительно обеспокоены блокировкой, которую будет выполнять действие вашего контроллера, пока оно ожидает ответа от API геолокации, вы можете создать собственную систему очередей для своих пользователей API.Поток выглядит примерно так:

  1. Пользователь делает запрос к вашей конечной точке
  2. Ваша конечная точка вставляет запись в таблицу базы данных с именем GeoResults со статусом «обработка»,и пустой текст ответа.Получите идентификатор этой записи.
  3. Ваша конечная точка запускает работу, как вы делаете сейчас, но теперь вы также передаете идентификатор записи GeoResults, которую вы создали.
  4. Ваша конечная точка даетпользователю URL-адрес для проверки этой записи в GeoResults.
  5. Ваш потребитель начинает опрашивать эту конечную точку, пока не увидит состояние «завершено»
  6. Когда ваше фоновое задание завершено, он обновляет свою записьв GeoResults (так как он имеет идентификатор) со статусом «завершено» и назначает текст ответа геолокации.
  7. Ваш потребитель видит обновление и получает ответ.
...