Wisper и Grape возвращают результаты запроса POST

У меня есть простая конечная точка POST Grape с Wisper pub/sub в фоновом режиме:

module Something
  class Doit < Grape::API
    post :now do
      service = SomePub.new
      service.subscribe(SomeSub.new)
      service.call(params)
    end
  end
end

Здесь SomeSub где собственно расчеты происходят:

class SomeSub
  def do_calculations(payload)
     {result: "42"}.to_json
  end
end

SomePub тоже просто:

class SomePub
  include Wisper::Publisher

  def call(payload)
    broadcast(:do_calculations, payload)
  end
end

Так что мне нужно ответить JSON {result: "42"}когда звонит Виноград post :now конечная точка.

К сожалению, это не работает так, и у меня есть:

{"local_registrations":[{"listener":{},"on":{},"with":null,"prefix":"","allowed_classes":[],"broadcaster":{}}]}

Этот пример из вики Wisper не слишком помогает ( https://github.com/krisleech/wisper/wiki/Grape)

Любые идеи, как на самом деле передать SomePub#do_calculations результаты, в результате вызова конечной точки Grape?

1 ответ

Решение

Смысл паттерна PubSub в том, что Publisher совершенно не знает своих подписчиков. То, что вы пытаетесь достичь, это передать результат подписчика обратно в Publisher, что противоречит всей идее.

Однако вы можете сделать своего подписчика также издателем и собирать ответы у отдельного подписчика.

Пожалуйста, обратите внимание, что это пример кода, так как у меня под рукой нет установленного Grape (но, надеюсь, он работает):

class ResponseListener
  attr_reader :response

  def initialize
    @response = {}
  end

  def collect_response(item)
    @response.merge!(item) # customize as you wish
  end
end

class SomeSub
  include Wisper::Publisher

  def do_calculations(payload)
     broadcast(:collect_response, result: "42")
  end
end

module Something
  class Doit < Grape::API
    post :now do
      response_listener = ResponseListener.new
      # globally subscribe response_listener to all events it can respond to
      Wisper.subscribe(response_listener) 

      service = SomePub.new
      service.subscribe(SomeSub.new)
      service.call(params)

      response_listener.response.to_json # render collected response
    end
  end
end
Другие вопросы по тегам