2015-07-26 33 views
21

मैं एस 3 में अपलोड की गई फाइल को संसाधित करने की कोशिश कर रहा हूं। चूंकि getObject प्रसंस्करण से पहले असंतुलित मुख्य कार्य समाप्त होता है, और एडब्ल्यूएस 3-4 सेकंड में लैम्ब्डा को मारता है।AWS Lambda के अंदर async क्रियाओं का इंतजार कैसे करें?

भी बदतर, प्रसंस्करण विधि को भी उस में async कार्य किया है - यह http कॉल करता है।

exports.handler = function(event, context) { 
    // Get the object from the event and show its content type 
    var bucket = event.Records[0].s3.bucket.name; 
    var key = event.Records[0].s3.object.key; 
    var params = { 
     Bucket: bucket, 
     Key: key 
    }; 
    s3.getObject(params, function(err, data) { 
     if (err) { 
      ... 
     } else { 
      processFile(data.Body.toString(), 0); 
      console.log("ok"); 
     } 
    }); 
    //need to wait here till processFile is done 
}; 

processFile = function(content, start) { 
    ... build url to call 
    http.get(url, function(res) { 
    console.log("Got response: " + res.statusCode + "); 
    processFile(content, start + 1); 
    }); 
} 

मुझे पता NodeJS में async है लेकिन यह अमेज़न से शामिल नहीं है कि;:

उच्च स्तर पर, की तरह मेरे कोड दिखता है दोनों की आवश्यकता होती है ('async') या आवश्यकता होती है ('नींद) त्रुटियों का कारण बनती है।

लैम्ब्डा टाइमआउट 60 सेकंड के लिए कॉन्फ़िगर है, लेकिन यह 3-4 सेकंड में बाहर निकालता है।

+0

मैं एडब्ल्यूएस लैम्ब्डा के साथ इसी तरह के मुद्दों को देखने, और बढ़ती निष्पादन विंडो के तार्किक असर नहीं टाइमआउट सेटिंग की पुष्टि कर सकते हैं ... मेमोरी बढ़ाने से आवंटन * करता * लगते उपलब्ध निष्पादन समय बढ़ाने के लिए, लेकिन अजीब प्रभाव अभी भी मनाए जाते हैं। – ericpeters0n

+0

क्या आपको याद है कि आपने इसे कैसे हल किया? – Juvaly

उत्तर

5

मुझे लगता है कि आपका लैम्ब्डा फ़ंक्शन context.done() कॉल के साथ समाप्त होना चाहिए। उदाहरण के लिए, यह इस तरह से जोड़ने का प्रयास करें:

s3.getObject(params, function(err, data) { 
    if (err) { 
     ... 
     context.done("Error: " + err.stack); 
    } else { 
     processFile(data.Body.toString(), 0); 
     console.log("ok"); 
     context.done(null, "success"); 
    } 
}); 
+0

मेरे पास पिछले हैंडलर में context.done है, लेकिन लैम्ब्डा को पहले समाप्त कर दिया गया है कि यह – st78

+2

है क्या आपके पास s3.getObject कॉलबैक के बाद context.done है? क्या आपने पिछले हैंडलर से context.done को हटाने का प्रयास किया था और इसे केवल s3.getObject कॉलबैक में रखा था, जैसा मैंने ऊपर दिखाया था? शायद आपकी कॉलबैक के बाहर context.done को s3.getObject कॉलबैक पूरा होने से पहले भी बुलाया जा रहा है। – rk2

7

async शामिल नहीं है, लेकिन इसका मतलब यह नहीं है कि आप इसे अपने आप को नहीं जोड़ सकते। बस पैकेज को स्थानीय रूप से जोड़ें (npm install async), और अपना Lambda फ़ंक्शन अपलोड करने से पहले अपने ज़िप में node_modules फ़ोल्डर शामिल करें।

आप अलग से देव निर्भरता को संभालने के लिए चाहते हैं (उदा .: परीक्षण, aws-sdk अपने कार्य स्थानीय स्तर पर आदि निष्पादित करने के लिए,), आप अपने package.json में devDependencies के तहत उन्हें जोड़ सकते हैं। साथ ही, यदि आप अपने कोड को विकसित करने, परीक्षण करने, तैनात करने और प्रचार करने की प्रक्रिया को स्वचालित करना चाहते हैं, तो ये दो प्रतिनिधि बहुत आसान हो जाएंगे।

Grunt routine to test, package and deploy your lambdas

Command line tool for running and deploying your lambda functions

5

बस एक कार्यक्रम है कि आप समय की एक निश्चित राशि में चला सकते हैं के रूप में लैम्ब्डा की Think। तथ्य यह है कि आप एसिंक्रोनस कॉल करते हैं क्योंकि यह (वर्चुअल) प्रोसेसर संभावित रूप से उन कॉलों को अंतःस्थापित कर सकता है। हालांकि, अगर आपके लैम्ब्डा कार्यक्रम का कोई भी हिस्सा आवंटित समय से पूरा करने में अधिक समय लगता है, तो निष्पादन विफल हो जाएगा। यह समझौता आपके द्वारा किया गया है और यह है कि अमेज़ॅन कैसे पैसा कमाता है; आपको अधिक समय या स्मृति बेचकर।

ठीक करने के लिए कि आपकी ओर से आप स्मृति अपने लैम्ब्डा समारोह आवंटित किया है बढ़ा सकते हैं। यह न केवल आपकी रैम बढ़ाता है बल्कि आपके वर्चुअल प्रोसेसर की गति भी बढ़ाता है। एक और चीज जो आप कर सकते हैं वह टाइमआउट बढ़ाती है। एडब्ल्यूएस लैम्ब्डा अब आपको 512 एमबी रैम तक और प्रसंस्करण के 5 मिनट तक की अनुमति देता है। इस पोस्ट के अनुसार उन नंबरों में बदलाव हो सकता है इसलिए नवीनतम सीमाओं के लिए here देखें। इस सेटिंग को बदलने के लिए, अपने फ़ंक्शन पर जाएं, फिर कॉन्फ़िगरेशन और अंत में उन्नत।

0

आप इसके बजाय synchronous कॉल करना चाहते हैं; चूंकि आप एक ही लैम्ब्डा फ़ंक्शन में अपनी फ़ाइल को संसाधित कर रहे हैं।

किसी कारण से आप एक कॉलबैक प्राप्त करना चाहते हैं; आप या तो सीधे लैम्ब्डा का आविष्कार कर सकते हैं या कुछ ऐसा कर सकते हैं जो लैम्ब्डा घटना उत्पन्न करे। ध्यान दें कि लैम्ब्डा कार्यों को स्टेटलेस माना जाता है; तो आपको सभी आवश्यक जानकारी में गुजरना चाहिए।

+3

सही, मुझे node.js के तहत सिंक्रनाइज़ रूप से s3.getObject करने का कोई तरीका नहीं मिला, और इसे जावा पर फिर से लिखना। – st78

+0

क्षमा करें; node.js के साथ मेरी परिचितता काफी सीमित है – Neil

3

आप के साथ-साथ आप एक zip फ़ाइल इस तरह के रूप में अपने समारोह अपलोड करने की आवश्यकता require('async'); पैक या require('sleep'); पैक का उपयोग करना चाहते हैं:

Creating a Deployment Package (Node.js)

Zip सभी फ़ोल्डर की सामग्री के रूप में मैं इस में समझाने साथ ही प्रश्न:

MQTT in AWS Lambda function for Alexa Javascript

तुल्यकालिक प्रसंस्करण के बारे में है, तो आप उपयोग कर सकते हैं

async.series([ 
    function(callback) { 
     // to do the function 1 
     callback(); 
    }, 
    function(callback) { 
     // to do the function 2 
     callback(); 
    }, 
    function(callback) { 
     // to do the function 3 
     callback(); 
    } 
], function(err) { 
    // to do the function if any error happens... 

    if (err) { 
     //... 
    } 
    //.... 
}); 

इस तरह lambda कार्य करेंगे तुल्यकालिक काम करता है: require('async'); सामान्य रूप से, बस async.series समारोह इस तरह का प्रयोग है।

मुझे आशा है कि आपकी मदद करें।

8

मेरे पास मेरे हाथों पर एक ही समस्या थी।

समस्या यह है कि जावास्क्रिप्ट इवेंट लूप खाली है इसलिए लैम्ब्डा सोचता है कि यह हो गया है।

इस प्रकार मैंने इस समस्या को हल किया। मुझे एहसास है कि यह आदर्श नहीं है, और मेरी इच्छा है कि एक बेहतर तरीका था, लेकिन मैं नहीं चाहता था) पुस्तकालयों को जोड़ें, बी) लैम्ब्डा आमंत्रण समन्वय, या सी) दूसरी भाषा में स्विच करें।

दिन के अंत में यह काम करता है।

exports.handler = (event, context, callback) => { 
 
     var response; 
 
     var callBackCount; 
 

 
     /* 
 
     Ensures the javascript event loop is never empty. 
 
     This is the key to keeping lambda from exiting early 
 
     */ 
 
     setInterval(function(){}, 1000); 
 

 
     /* 
 
     Tell lambda to stop when I issue the callback. 
 
     This is super important or the lambda funciton will always go until it hits the timeout limit you set. 
 
     */ 
 
     context.callbackWaitsForEmptyEventLoop = false; 
 
     
 
     //My way of determining when I'm done with all calls 
 
     callBackCount = 0; 
 
     
 
     //My info to return 
 
     response = ""; 
 
     
 
     //Various functions that make rest calls and wait for a response 
 
     asyncFunction1(); 
 
     asyncFunction2(); 
 
     asyncFunction3(); 
 

 
     //Same for asyncFunction 2 and 3 
 
     function asyncFunction1(){ 
 
      response += callBackResponseForThisMethod; 
 
     
 
      returnResponse(); 
 
     } 
 

 
     function returnReponse(){ 
 
      callBackCount++; 
 

 
      if(callBackCount == 3){ 
 
       //Lambda will stop after this as long as context.callbackWaitsForEmptyEventLoop was set to false 
 
       callback(null, JSON.stringify(response)); 
 
      } 
 
     } 
 

 
    };

http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

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