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?
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