0

I have a Tornado web server running several web services. I need one of the operations in Service A to call an operation on Service B. I'm using Suds to make this call to Service B. At the moment everything hangs unless I put the Suds call into a separate thread, but now I need to get data from that call (in Thread 1) back into the main thread so I can send it back to the original requesting web service (Service A). Some code:

if input.payment_info.issuer == 'Amex':
    def t1():
        url = 'http://localhost:8080/PaymentService?wsdl'
        client = Client(url)
        result = client.service.process_amex(payment_info.issuer, payment_info.number, payment_info.sort_code)

    t = Thread(target=t1)
    t.start()
    if result == "Success":
        return result #How can I access it to return it to the main service

Apologies if this is unclear, I know threading is a complex issue but I don't see any other options here as the code hangs without it.

Edit: To be clear, I'm not using suds to call Service A. The only instance of suds is being used to call Service B.

I've also tried using a Queue as per Alex Martelli's post here (http://stackoverflow.com/a/2846697/559504) but it hangs again.

if input.payment_info.issuer == 'Amex':
        def t1(q):
            url = 'http://localhost:8080/PaymentService?wsdl'
            client = Client(url)
            result = client.service.process_amex(payment_info.issuer, payment_info.number, payment_info.sort_code)
            q.put(result)
        q = Queue.Queue()
        t = Thread(target=t1, args=(q))
        t.daemon = True
        t.start()
        result = q.get()
        if result == "Success":
            return "Success"
johnharris85
  • 17,264
  • 5
  • 48
  • 52
  • you could call IOLoop.add_callback in suds thread to execute the callback with results in the main tornado thread (similar to twisted reactor.callFromThread – jfs Oct 18 '12 at 18:31
  • Thanks, not sure how that would work in my example, can you give some code please? – johnharris85 Oct 19 '12 at 09:15
  • you could add at the end of t1 in your first example: `ioloop_instance.add_callback(functools.partial(send_to_serviceA_function, result))`. I don't use tornado so there might be a simpler solution e.g., some helper that automatically executes blocking function in a worker thread and calls a callback with the returned value in the main thread. – jfs Oct 19 '12 at 10:50

1 Answers1

0

Here's a fragment for a multi-threaded tkinter application I have which uses a Queue to pass data from one thread to another. I think there's probably enough for you to use it as a template.

def check_q(self, _):
    log = self.logwidget
    go = True
    while go:
        try:
            data = queue.get_nowait()
            if not data:
                data = '<end>'  # put visible marker in output
                go = False
            log.insert(END, data)
            log.see(END)
        except Queue.Empty:
            self.after(200, self.check_q, ())
            go = False
martineau
  • 119,623
  • 25
  • 170
  • 301