2012-09-04 17 views
10

में @ ndb.tasklet या @ ndb.synctasklet का उपयोग करके मेरे पास POST विधि है जो कुछ कार्यलेट्स को कॉल करती है। इन कार्यलेटों में उनमें पैदावार होती है, और मेरे पास मेरे कोड में x.put_async() है। इसलिए मैं नहीं चाहता कि सभी एसिंक सामग्री पूरी हो जाए। इसलिए मैंने अपने सभी कार्यलेटों को सजाया, जो @ndb.tasklet के साथ केवल छोटे कार्य हैं। इसके अलावा, मेरी POST विधि के शीर्ष पर, मेरे पास है:Google ऐप इंजन

@ndb.toplevel 
def post(self): 

हालांकि, documentation में यह कहा गया है:

लेकिन कोई हैंडलर विधि उपज उपयोग करता है, कि पद्धति अभी भी होने की में लिपटे की जरूरत है एक और सजावट, @ ndb.synctasklet; अन्यथा, यह उपज पर निष्पादन करना बंद कर देगा और खत्म नहीं होगा।

वास्तव में मेरी विधि में उपज है। यह पहले से ही @ ndb.tasklet में लपेटा गया है। क्या मैं इसे @ ndb.synctasklet से बदलता हूं या क्या मैं दोनों का उपयोग करता हूं (यदि ऐसा है तो मैं दोनों का उपयोग कैसे करूं?)

इसके अलावा, this thread देखें जिसमें कुछ प्रासंगिकता है। मैंने भी एक मुद्दा देखा जहां मेरा अनुरोध बिना किसी आउटपुट के वापस लौटाएगा, लेकिन यह अप्रतिबंधित है। यह हर 15 मिनट या निरंतर उपयोग के साथ होता है। मेरे पास केवल app = ndb.toplevel(webapp2.WSGIApplication([..]) था, लेकिन अब मैंने @ndb.toplevel को मुख्य POST विधियों में जोड़ा है, लेकिन समस्या अभी भी बनी हुई है।

क्या मुझे @ndb.tasklet उन विधियों के शीर्ष पर रखना चाहिए जिनके पास put_async() है? (क्या मुझे इसे सुरक्षित रखने के लिए हर विधि के शीर्ष पर रखना चाहिए? इसके लिए डाउनसाइड्स क्या हैं?)

उत्तर

10

हैंडलर के बारे में और @ ndb.toplevel और @ ndb.synctasklet का उपयोग करके: जिस तरह से मैं समझ गया था वह था आपको हैंडलर पर @ ndb.synctasklet और @ ndb.toplevel दोनों का उपयोग करने की आवश्यकता है। सभी उप-कार्यलेटों को केवल @ ndb.tasklet सजावट की आवश्यकता होती है। जैसे

class Foo(ndb.Model): 
    name = ndb.StringProperty() 

    @ndb.tasklet 
    def my_async(self): 
     .... 
     #do something else that yields 
     raise ndb.Return("some result") 


@ndb.toplevel 
@ndb.synctasklet 
def post(self): 
    foo = Foo(name="baz") 
    yield foo.put_async() 
    yield foo.my_async() 
    .... 

हालांकि। source को देखते हुए ऐसा लगता है कि वास्तव में वैसे भी एक synctasklet है @ ndb.toplevel:

def toplevel(func): 
    """A sync tasklet that sets a fresh default Context. 

    Use this for toplevel view functions such as 
    webapp.RequestHandler.get() or Django view functions. 
    """ 

हैंडलर में पैदावार के साथ एक छोटे से परीक्षण चल रहा है और साथ @ ndb.toplevel अभी भी काम करने लगता है सजाया गया है और लगता है कि आप हैंडलर से @ ndb.synctasklet हटा सकते हैं।

चाहे आपको put_async(): पर कॉल करने वाले तरीकों पर @ ndb.tasklet शामिल करना चाहिए या नहीं, यदि आप put_async() पर उपज नहीं कर रहे हैं, तो आपको आसपास के विधि पर @ ndb.tasklet शामिल करने की आवश्यकता नहीं है (@ ndb.toplevel put_async() से परिणाम प्राप्त करने में संभाल लेंगे)

+12

अच्छा उत्तर! नियमों को संक्षेप में सारांशित किया जा सकता है: (1) यदि कोई फ़ंक्शन "उपज" का उपयोग करता है तो इसे ndb.tasklet, ndb.synctasklet, या ndb.toplevel होना चाहिए। (2) ndb.tasklet में लिपटे एक फ़ंक्शन एक भविष्य देता है (और आप या तो इसे उपज सकते हैं या get_result() को स्पष्ट रूप से कॉल कर सकते हैं)। (3) ndb.synctasklet इसे ndb.tasklet में लपेटने जैसा है लेकिन निश्चित रूप से get_result() को कॉल कर रहा है। (4) ndb.toplevel बस ndb.synctasklet की तरह है लेकिन पूरा करने के लिए सभी लंबित परिचालनों की भी प्रतीक्षा करता है। –