2015-06-09 14 views
14

करता है मैं एक लैम्ब्डा समारोह के लिए निम्न कोड है:क्वैरी DynamoDB कुछ भी नहीं

console.log('Loading function'); 
var aws = require('aws-sdk'); 
var ddb = new aws.DynamoDB(); 

function getUser(userid) { 
    var q = ddb.getItem({ 
     TableName: "Users", 
     Key: { 
      userID: { S: userid } } 
     }, function(err, data) { 
      if (err) { 
       console.log(err); 
       return err; 
      } 
      else { 
       console.log(data); 
      } 
    }); 
    console.log(q); 
} 


exports.handler = function(event, context) { 
    console.log('Received event'); 
    getUser('user1'); 
    console.log("called DynamoDB"); 
    context.succeed(); 
}; 

मैं एक [उपयोगकर्ता] तालिका है कि इस तरह के रूप में परिभाषित किया गया है है:

{ 
    "cognitoID": { "S": "token" }, 
    "email": { "S": "[email protected]" }, 
    "password": { "S": "somepassword" }, 
    "tos_aggreement": { "BOOL": true }, 
    "userID": { "S": "user1" } 
} 

जब मैं फोन फ़ंक्शन (एडब्ल्यूएस कंसोल या सीएलआई से) मैं लॉग में संदेशों को देख सकता हूं लेकिन getItem() के लिए कॉलबैक कभी नहीं कहा जाता है।

मैंने कोई कॉलबैक के साथ getItem (पैराम्स) करने की कोशिश की, फिर पूर्ण, सफलता और विफलता के लिए कॉलबैक परिभाषित किया लेकिन जब मैं भेजता हूं(), यहां तक ​​कि पूर्ण कॉलबैक भी नहीं कहा जाता है।

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

मैंने बैचगेटइटम, getItem, listTables और स्कैन के विभिन्न कार्यों के साथ प्रयास किया। नतीजा वही है, कोई त्रुटि नहीं है लेकिन कॉलबैक फ़ंक्शन कभी नहीं कहा जाता है।

मैं शर्त लगा रहा हूं कि अगर मैं लैम्ब्डा का उपयोग किए बिना डायनेमो डीबी पूछता हूं तो मुझे परिणाम मिलेंगे इसलिए मैं वास्तव में सोच रहा हूं कि यहां कुछ भी क्यों नहीं हो रहा है।

मैं फ़ंक्शन के लिए एक भूमिका निभाता हूं और मैंने एक नीति बनाई है जो मुझे डायनेमो डीबी में कार्यक्षमताओं तक पहुंच की अनुमति देगी, लेकिन मुझे कोई फायदा नहीं हुआ।

नीति इस तरह दिखता है:

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
     { 
      "Effect": "Allow", 
      "Action": [ 
       "lambda:InvokeFunction" 
      ], 
      "Resource": "arn:aws:lambda:*:*:*" 
     }, 
     { 
      "Effect": "Allow", 
      "Action": [ 
       "dynamodb:GetItem", 
       "dynamodb:BatchGetItem", 
       "dynamodb:Scan", 
       "dynamodb:PutItem", 
       "dynamodb:Query", 
       "dynamodb:GetRecords", 
       "dynamodb:ListTables" 
      ], 
      "Resource": "arn:aws:dynamodb:*:*:*" 
     }, 
     { 
      "Action": [ 
       "logs:*" 
      ], 
      "Effect": "Allow", 
      "Resource": "*" 
     } 
    ] 
} 

मैं सिम्युलेटर में नीति भाग गया और यह काम किया के रूप में मैंने सोचा कि यह होगा। सुझाव?

+0

क्या आपको एक संदेश मिल रहा था जो कहता है कि अनुरोध पूरा करने से पहले प्रक्रिया समाप्त हो गई है? –

+0

नहीं क्योंकि मेरे पास एक संदर्भ था।() या context.succeed() वहां कॉल करें। मुद्दा यह है कि JSNode स्क्रिप्ट असीमित है और जब आप डायनेमो डीबी को कॉल करते हैं, तो लैम्बडा फ़ंक्शन समाप्त होने के बाद से इसकी कॉलबैक कभी नहीं कह सकती है। तथ्य की बात है, डायनेमो डीबी कार्रवाई में शुरू करने का समय भी नहीं है। –

उत्तर

13

तो, यह पता चला है कि कोड सही है। समस्या यह है कि डायनेमोड एपीआई उन सभी कॉलबैक का उपयोग करता है और मूल रूप से फ़ंक्शन समाप्त होता है इससे पहले कि डेटा पुनर्प्राप्त किया गया हो।

सबसे तेज़ फिक्स context.succeed() कॉल को निकालना है और डेटा पुनर्प्राप्त किया जाएगा। निश्चित रूप से एसिंक मॉड्यूल का उपयोग करने में मदद मिलेगी और यदि आप इसका उपयोग नहीं करना चाहते हैं, तो बस अपने कॉलबैक में काउंटर या बूलियन जोड़ें और फिर मूल्य बदलने तक प्रतीक्षा करें, यह दर्शाता है कि कॉलबैक को कॉल किया गया है (किस तरह का अगर आप इसके बारे में सोचते हैं तो बेकार है)

+6

कुछ भी नहीं के लिए काउंटर और लूपिंग जोड़ने के बजाय, मुझे लगता है कि कॉलबैक फ़ंक्शन से 'context.succeed()' को कॉल करना सबसे अच्छा है, जैसे: \t console.log (डेटा); \t context.succeed (डेटा); –

4

मेरे पास कुछ समान समस्याएं थीं और मुझे कई उपयोगी संसाधन नहीं मिला। यहां मैं क्या कर रहा हूं। शायद कोई स्मार्ट हमें बता सकता है कि यह सबसे अच्छा है या नहीं।

function getHighScores(callback) { 
    var params = { 
     TableName : 'sessions', 
     ScanFilter: {"score":{"AttributeValueList":[{"N":"0"}], "ComparisonOperator":"GT"}}, 
    }; 
    var dynamo = new AWS.DynamoDB(); 
    dynamo.scan(params, function(err, data) { 
     if (err) { 
      console.log (err) 
      callback(err); 
     } else { 
      callback(data.Items); 
      console.log(data.Items); 
     } 
    }); 
} 



getHighScores(function (data) { 
    console.log(data); 
    context.succeed(data); 
}); 

सारांश में, छोटे कार्य करने के लिए मुख्य कार्य के माध्यम से कॉलबैक की पासबैक होने, आवेदन डायनमो को पूरा करने तक जारी रखने के लिए अनुमति देता है। संदर्भ रखें। द्वितीयक फ़ंक्शन में आगे बढ़ें या वहां अन्य फ़ंक्शन जारी रखें।

+0

इस तरह से मैं इसे कर रहा हूं। यदि आप इसके बारे में सोचते हैं, तो समस्या डायनेमो डीबी या लैम्ब्डा नहीं है बल्कि यह तथ्य है कि लैम्ब्डा फ़ंक्शन नोडजेएस कोड है, जिसका अर्थ है कि सब कुछ असीमित है और इसलिए आपको जगह पर कॉलबैक होना चाहिए। कभी-कभी यह बहुत सुविधाजनक नहीं है लेकिन यह एसिंक मोड में सब कुछ कोडिंग के आसपास अपने सिर को लपेटने का मामला है :) –

+0

वाह, मुझे वाकई खुशी है कि आपने इसे पोस्ट किया है। मैं इसे घंटों तक काम करने की कोशिश कर रहा हूं। मैंने दस्तावेज़ों में आपके पास जो कुछ भी है, उससे कुछ भी नहीं देखा, लेकिन यह काम करता है! – dudeman

0

कॉलबैक नरक से बचने के लिए, वादा का उपयोग करें। Funfunfunction नामक लड़के द्वारा यूट्यूब पर कुछ सुंदर अच्छे ट्यूटोरियल हैं।

2

मेरी समस्या यह है कि मेरी लैम्ब्डा एलिस्टी कैश से कनेक्ट करने के लिए वीपीसी में चल रही थी।इससे सार्वजनिक इंटरनेट संसाधनों जैसे डायनेमोडीबी और एपीआई गेटवे को अनिश्चित काल तक लटका दिया जाता है। डायनेमो डीबी तक पहुंचने के लिए मुझे अपने वीपीसी के भीतर एक एनएटी गेटवे स्थापित करना पड़ा।

+0

इस उत्तर ने वास्तव में मेरी मदद की लेकिन मैंने एलैस्टिक कैश से कनेक्ट करने के लिए एक और लैम्ब्डा बनाया, इसलिए मुझे अपने वीपीसी में एनएटी गेटवे जोड़ने की ज़रूरत नहीं है, फिर केवल एलिस्टी कैश लैम्ब्डा मेरे वीपीसी में है और मैं इसे अपने मुख्य लैम्ब्डा से आमंत्रित करता हूं (जो कि वीपीसी में नहीं) – fpg1503

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