webentwicklung-frage-antwort-db.com.de

Warum läuft die AWS Lambda-Funktion immer ab?

Ich teste aws lambda und verwende nodejs mit der Version 4.3. Ich kann alle Anweisungen in meiner Handler-Funktion innerhalb des Konsolentests erfolgreich abschließen. Dazu gehört auch das Herstellen einer Verbindung zu einem Mongodb-Host in unserem VPC. Aber die Funktion läuft immer ab. Ich habe mehrere Beiträge und Ressourcen gefunden, in denen der Rückruf und das Festlegen von Eigenschaften für den Kontext und die Berechtigungen der IAM-Rolle beschrieben werden. Unabhängig davon, was ich mache, endet das Zeitlimit. Aktueller Code:

'use strict';

var Mongoose = require('mongoose');
var Device = require('./device_model');
var Alarm = require('./alarm_model');
var Event = require('./event_model');

var mongoConnection = process.env.MONGO_URL;

var connection = Mongoose.connect(mongoConnection);

Mongoose.connection.once('open', function() {
    console.log("Connecting to mongo at: " + mongoConnection);
    console.log("Mongoose connection in lambda opened");
});

Mongoose.connection.on('error', function(){
    console.error("Error creating mongoose connection in lambda, exiting!");
    process.exit(1);
});

exports.check_alarms = function(event, context, callback) {

    context.callbackWaitsForEmtpyEventLoop = false;
    console.log("The incoming event: " + JSON.stringify(event));

    var device = null;
    Device.findByUUID(event.uuid, function(error, result){
        if(!error){
            device = result;
            console.log("the device: " + JSON.stringify(device));
            if(event.Ale && event.Ale.length > 0) {
                console.log("We have an alarm, checking if already set");
                callback(null, {"status":"alarms"});
            } else {
                console.log("Event contains no alarm; checking for historic active");
                callback(null, {"status":"no alarms"});
            }
        } else {
            console.log("there's a problem on mongo");
            callback("problem", "status not so good");
        }
    });

    callback(null, {"status":"outside of device find block"});
}
10
wkhatch

Sie haben einen Tippfehler:

context.callbackWaitsForEmtpyEventLoop = false;

sollte sein:

context.callbackWaitsForEmptyEventLoop = false;

Folgendes sagt die Dokumentation über das Verhalten von callbackWaitsForEmptyEventLoop:

callbackWaitsForEmptyEventLoop

Der Standardwert ist true. Diese Eigenschaft ist nur nützlich, um das Standardverhalten des Rückrufs zu ändern. Standardmäßig wartet der Rückruf, bis die Node.js-Laufzeitereignisschleife leer ist, bevor der Prozess eingefroren und die Ergebnisse an den Aufrufer zurückgegeben werden. Sie können diese Eigenschaft auf false setzen, um AWS Lambda anzufordern, den Prozess kurz nach dem Aufruf des Callbacks einzufrieren, auch wenn Ereignisse in der Ereignisschleife vorhanden sind. AWS Lambda friert den Prozess, alle Statusdaten und die Ereignisse in der Ereignisschleife Node.js ein (alle verbleibenden Ereignisse in der Ereignisschleife werden verarbeitet, wenn die Lambda-Funktion als nächstes aufgerufen wird und AWS Lambda den eingefrorenen Prozess verwendet). Weitere Informationen zum Rückruf finden Sie unter Verwenden des Rückrufparameters .

Minimales Beispiel:

// Times out due to typo
exports.function1 = (event, context, callback) => {
    setInterval(() => console.log('Long wait'), 100000);
    context.callbackWaitsForEmtpyEventLoop = false;
    callback(null, 'Hello from Lambda');
};

// Returns successfully
exports.function2 = (event, context, callback) => {
    setInterval(() => console.log('Long wait'), 100000);
    context.callbackWaitsForEmptyEventLoop = false;
    callback(null, 'Hello from Lambda');
};
15
wjordan

Wenn jemand so verwirrt war, wie ich callbackWaitsForEmptyEventLoop zu neuen Alexa-Projekten hinzugefügt habe, die folgendermaßen aussehen:

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
      GetNewFactHandler,
      HelpHandler,
      ExitHandler,
      FallbackHandler,
      SessionEndedRequestHandler,
  )
  .addRequestInterceptors(LocalizationInterceptor)
  .addErrorHandlers(ErrorHandler)
  .lambda();

Beispielprojekt hier: https://github.com/Alexa/skill-sample-nodejs-fact/blob/master/lambda/custom/index.js

Diese Lösung hat für mich funktioniert:

// create a custom skill builder
const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = (event, context, callback) => {
  // we need this so that async stuff will work better
  context.callbackWaitsForEmptyEventLoop = false

  // set up the skill with the new context
  return skillBuilder
    .addRequestHandlers(
      GetNewFactHandler,
      HelpHandler,
      ExitHandler,
      FallbackHandler,
      SessionEndedRequestHandler,
    )
    .addRequestInterceptors(LocalizationInterceptor)
    .addErrorHandlers(ErrorHandler)
    .lambda()(event, context, callback);
}
1
tdon