2016-02-28 34 views
5

मेरे पास एक साधारण AWS Lambda फ़ंक्शन है जो S3 बाल्टी में सहेजी गई छवियों पर कुछ सत्यापन करता है। मैं छवि डाउनलोड करने और इसे संसाधित करने के लिए async.waterfall का उपयोग कर रहा हूं, लेकिन इससे पहले कि मैं पहले झरना समारोह में भी प्रवेश करता हूं, मैं अपने S3 PutObject ट्रिगर से प्राप्त होने वाले ईवेंट डेटा पर कुछ बुनियादी सत्यापन करता हूं, विशेष रूप से आकार की जानकारी (event.Records[0].s3.object.size)। यदि ईवेंट मेरी छवि का संदर्भ देता है जो मेरे MAX_SIZE से बड़ा है, तो मैं निष्पादन समाप्त करने के लिए context.fail(new Error("Validation error: the file is too big.")) का उपयोग करता हूं।AWS Lambda फ़ंक्शन संदर्भ के बाद थोड़ा सा जारी रहता है।

यह सब ठीक काम कर रहा है, लेकिन मुझे अपने लॉग में नोटिस है कि त्रुटि लॉग होने के बाद, फ़ंक्शन बाहर निकलने से पहले थोड़ा सा चल रहा है। उदाहरण के लिए, मेरे async.waterfall कॉल में पहला फ़ंक्शन कॉल किया जाता है (यानी लॉग में उस फ़ंक्शन से एक संदेश दिखाता है)। मैंने संदर्भ के तुरंत बाद context.done(errorMessage) जोड़ने का भी प्रयास किया। ठीक है, और कोड के कुछ और लाइनों के साथ इसे निष्पादित किया जाता है (यानी मैं जिस संदेश में प्रवेश करता हूं) लॉग हो जाता है।

क्या यह अपेक्षित व्यवहार है? मुझे दस्तावेज़ों में इसका कोई उल्लेख नहीं मिला। क्या फ़ंक्शन से बाहर निकलने में थोड़ा सा समय लगता है या क्या मैं async.waterfall से पहले हैंडलर फ़ंक्शन में कोड की सिंक्रोनस प्रकृति को गलत समझा रहा हूं?

नीचे मेरा कुछ कोड है। सभी console.log संदेश जो context.fail के बाद दिखाए गए हैं लॉग पर मुद्रित हो जाते हैं, जिन्हें मैं होने की उम्मीद नहीं करता।

exports.handler = function(event, context) { 
    console.log('Received event:', JSON.stringify(event, null, 2)); 

    if (event.Records[0].s3.object.size > MAX_FILE_SIZE) { 
    var error = new Error("Validation error: the file is too big.") 
    context.fail(error); 
    } 
    console.log('Event validation complete.') 

    var bucket = event.Records[0].s3.bucket.name; 
    var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); 
    var fileName = key.split("/")[1]; 
    var params = { 
    Bucket: bucket, 
    Key: key 
    }; 
    console.log('Starting processing of the following file: ' + JSON.stringify(params, null, 2)); 

    async.waterfall([ 
    function download(callback) { 
     // Download the image from S3 into a buffer. 
     console.log("Downloading the image from S3..."); 
     s3.getObject(params, function(err, data) { 
      if (err) { 
       callback(err); 
      } else { 
       callback(null, data); 
      } 
     }); 
    }, 
    ... 
    ], ...) 
} 

उत्तर

2

ऐसा लगता है कि यह अच्छी तरह से प्रलेखित नहीं है, भले ही व्यवहार की अपेक्षा की जा सके। context documentation कहता है fail() "विफलता इंगित करता है" लेकिन आगे निष्पादन को रोकने का वादा नहीं करता है।

context.fail()

लैम्ब्डा समारोह निष्पादन और सभी कॉलबैक एक संभाला अपवाद है, जिसके परिणामस्वरूप असफल पूरा, यह इंगित करता है।

अपने कोड के लिए अच्छी खबर यह है कि यह काफी context.fail() बुला आगे की प्रक्रिया से बचने के लिए के बाद return समारोह से करने के लिए आसान होना चाहिए।

+0

लंबे विलंब के लिए खेद है !! सहायता के लिए धन्यवाद! 'वापसी 'काम किया (Node.js v0.10.42 रनटाइम के लिए), लेकिन क्यों? क्या यह कहीं दस्तावेज है, या कुछ मुझे Node.js के बारे में पता होना चाहिए? http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html – readyornot

+0

सुधार, यह Node.js के नवीनतम समर्थित संस्करण में भी काम करता है (v4.3)। 'वापसी 'तुरंत निष्पादन में कटौती करता है, लेकिन मुझे अभी भी समझ में नहीं आता क्यों। यह यहां दस्तावेज नहीं है: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-mode-exceptions.html – readyornot

+0

मुझे उम्मीद है कि आपके कार्य को चलाने वाले नोड दुभाषिया और लैम्ब्डा के बीच एक प्राकृतिक डिस्कनेक्ट है पर्यावरण की निगरानी बुनियादी ढांचा।मैं केवल रक्षात्मक कोडिंग की सिफारिश कर सकता हूं। @ एमिस्पाउडर का जवाब कुछ और सटीक नियंत्रण प्रदान करता है, आप इसे आजमा सकते हैं। – James

9

मेरा मानना ​​है कि इस प्रश्न से पूछा गया था (और जेम्स का जवाब) क्योंकि aws lambda संरचना थोड़ा बदल गई है।

अब हैंडलर के पास third argument, 'कॉलबैक' है, जिसे स्क्रिप्ट के निष्पादन को रोकने के लिए कहा जा सकता है। इस पर निर्भर करते हुए कि आप इसे कैसे कॉल करते हैं, यह प्रक्रिया सफलतापूर्वक या किसी त्रुटि के साथ निकलता है। विशिष्टताओं के लिए उन दस्तावेज़ों को देखें।

इसके अतिरिक्त, संदर्भ संपत्ति, callbackWaitsForEmptyEventLoop देखें। यह सत्य पर डिफ़ॉल्ट है, लेकिन आप इसे गलत पर सेट करना चाहते हैं ताकि, कॉलबैक को कॉल करने के बाद, नोड प्रक्रिया रनटाइम लूप को साफ़ करने की प्रतीक्षा न करे, यानी आपकी Async कॉल फेंक दी जाती है।

+0

सिवाय उन्हें "फेंक दिया नहीं जाएगा", वे अभी भी वहां हैं, भले ही प्रक्रिया जमे हुए हो और उनके कॉलबैक निम्नलिखित लैम्ब्डा इनवोकेशन के भीतर चले जाएंगे। तो सावधान रहें। – nitely

संबंधित मुद्दे