0
import gnsq

class something():
    def __init__(self, pb=None, pk=None, address=None):
        self.pb = pb
        self.pk = pk
        self.address = address

    def connect(self):
        consumer = gnsq.Consumer(self.pb, 'ch', self.address)

        @consumer.on_message.connect
        def response_handler(consumer, msg):
           return msg.body

        consumer.start()

how would i get the return value of response_handler so in turn, I'd be able to pass to the parent function connect(), so when i call it, it will be returning the value of message.body from the child function.

I would think something like the following:

import gnsq

class something():
    def __init__(self, pb=None, pk=None, address=None):
        self.pb = pb
        self.pk = pk
        self.address = address

    def connect(self):
        consumer = gnsq.Consumer(self.pb, 'ch', self.address)

        @consumer.on_message.connect
        def response_handler(consumer, msg):
           return msg.body

        consumer.start()

       return response_handler

nsq = something('pb', 'pk', 'address')

# should print whatever message.body is
print nsq.connect() 

but It's not working. Note: consumer.start() is blocking

swoopy
  • 326
  • 4
  • 18

1 Answers1

1

What you're asking doesn't make sense in the context of what the Consumer() really is.

In your connect() method, you set up a consumer, set up a response handler and start the consumer with consumer.start(). From that point onward, whenever there is a message to consume, the consumer will call the handler with that message. Not just once, but again and again.

Your handler may be called many times and unless the consumer is closed, you never know when it will be done - so, there's no way your connect() method could return the complete result.

What you could do is have the connect method return a reference to a collection that will at any time contain all the messages collected so far. It would be empty at first, but after some time, could contain all the received messages.

Something like:

import gnsq

class Collector():
    def __init__(self, topic, address):
        self.topic = topic
        self.address = address
        self.messages = []

    def connect(self):
        self.messages = []
        consumer = gnsq.Consumer(self.pb, 'ch', self.address)

        @consumer.on_message.connect
        def response_handler(consumer, msg):
           self.messages.append(msg)

        consumer.start()
        return self.messages

I don't think this is really how you want to be using this, it would only really make sense if you provide more context on why and how you want to use this output.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • yea, so Im trying to build a flask server and this module build on top of gnsq. The module's goal is just to connect and receive messages from an nsq node, which in turn the flask server knows that the module is receiving something, then eventually flask sever will parse/process certain messages to be exposed to an endpoint or url, ideally I would run the flask server separately from the module. like `python flask_server.py` then `python gnsq_module.py` – swoopy Nov 18 '19 at 05:26
  • when you say at anytime, you mean even when the consumer.start() is in process? – swoopy Nov 18 '19 at 06:52
  • @swoopy, yes, although there's some ifs, buts and maybes that come along with communicating between processes that run in parallel. To keep things simple, I provided an example that simply uses a list, since I'm assuming the response handler and any code accessing the list would be running on the same thread. In a more realistic or more complicated situation, one might use something like `multiprocessing.Queue()` class to safely pass information between different processes, but that goes a bit beyond the question - we'd have to know a bit more about what you're actually trying to do. – Grismar Nov 19 '19 at 01:16