2016-07-07 30 views
0

In meiner Python Twisted-Anwendung muss ich Daten vom Client erhalten, einige Datenbankoperationen durchführen und - abhängig von Daten - einige Blockierungscode in separaten Thread ausführen.Mixed Deferred und DeferToThread zum Ausführen von Blocking-Code in separaten Thread

Bisher habe ich:

d = get_user(user_id) 

d.addCallback(do_something_with_input_data, input_data) 
d.addCallback(run_blocking_code) 
d.addCallback(save_data_into_db) 
d.addCallback(response_to_client) 

@defer.inlineCallbacks 
def get_user(self, user_id): 
    user = yield get_user_from_db(user_id) 
    defer.returnValue(user) 

def do_something_with_input_data(user, input_data): 
    # do smth... 
    return results 

@defer.inlineCallbacks 
def run_blocking_code(results) 

    threads.deferToThread(run_in_separate_thread, results) 
    return results 

@defer.inlineCallbacks 
def save_data_into_db(results) 
    yield save_in_db(results) 
    def.returnValue('OK') 

def response_to_client(response) 
    # send 'OK' to client 

Ist dies ein guter AnsatzdeferToThread() in run_blocking_code() anrufen? Wenn ja, wie kann ich warten bis Thread endet?

Antwort

1

Ich würde sagen, das allgemeine Konzept ist in Ordnung. Ich würde in etwas hinzufügen errbacks, und Sie müssen auch Ihre run_blocking_code-Funktion zu optimieren:

@defer.inlineCallbacks 
def run_blocking_code(results) 

    # the `deferToThread` returns a deferred 
    d = threads.deferToThread(run_in_separate_thread, results) 

    # let's wait for it here (need a yield for functions decorated with `inlineCallbacks`) 
    yield d 

    # now return its value to the next function in the callback chain 
    defer.returnValue(d.result)