There Are Four Lights
There Are Four Lights

Reputation: 1426

Wisper and Grape return results from a POST request

I have a simple POST Grape endpoint with Wisper pub/sub in a background:

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

Here is the SomeSub where actually calculations happens:

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

SomePub is simple too:

class SomePub
  include Wisper::Publisher

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

So what I need is to respond with the JSON {result: "42"}, when calling the Grape's post :now endpoint.

Unfortunately it doesn't work this way, and what I have is:

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

That example from Wisper's wiki doesn't help too much (https://github.com/krisleech/wisper/wiki/Grape)

Any ideas how to actually pass SomePub#do_calculations results, as a result of Grape's endpoint call?

Upvotes: 3

Views: 579

Answers (1)

Aleksey Shein
Aleksey Shein

Reputation: 7482

The point of PubSub pattern is that Publisher is completely unaware of its subscribers. What you are trying to achieve is to pass Subscriber's result back to Publisher, which is against all of the idea.

What you can do, however, is to make your subscriber also a publisher and collect responses in a separate subscriber.

Please, note, that this is sample code as I don't have Grape installed at hand (but, hopefully, it works):

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

Upvotes: 3

Related Questions