web-dev-qa-db-fra.com

La fonction AWS lambda cesse de fonctionner après une erreur de délai d'attente

J'ai une fonction lambda simple qui effectue des appels asynchrones de manière asynchrone, puis renvoie des données. 99% du temps cela fonctionne très bien. Chaque fois que l'API prend plus de temps que le délai d'expiration configuré par lambda, il génère une erreur comme prévu. Maintenant, le problème est que lorsque je passe des appels ultérieurs à la fonction lambda, cela me donne en permanence l'erreur de dépassement de délai.

 "errorMessage": "2016-05-14T22:52:07.247Z {session} Task timed out after 3.00 seconds"

Afin de vérifier que tel était le cas, j'ai réglé le délai d'attente lambda à 3 secondes et j'ai un moyen de déclencher ces deux fonctions dans le lambda.

Javascript

function now() { 
    return response.tell('success'); 
}

function wait() {
    setTimeout(function() { return response.tell('success'); }, 4000);
}

Lorsque j'appelle la fonction now, il n'y a pas de problèmes. Lorsque j'appelle la fonction wait, j'obtiens l'erreur de délai d'attente et tous les appels ultérieurs à now me donnent la même erreur.

Est-ce un comportement attendu? Je pense que tous les appels ultérieurs à la fonction lambda devraient fonctionner. Je comprends que je peux toujours augmenter le délai de configuration, mais préfère ne pas le faire.

35
jjbskir

Vous devriez chercher comment votre fonction handle fonctionne avec un context.callbackWaitsForEmptyEventLoop

Si ce type booléen est false, setTimeout ne sera jamais déclenché, car vous avez peut-être déjà répondu/géré l'invocation lambda. Mais si la valeur de callbackWaitsForEmptyEventLoop est true - alors votre code fera ce que vous recherchez.

En outre, il est probablement plus facile de gérer tout via les rappels directement, sans avoir besoin de délais d'attente "écrits à la main", de changements de délais de configuration, etc.

Par exemple.

function doneFactory(cb) { // closure factory returning a callback function which knows about res (response)
  return function(err, res) {
    if (err) {
      return cb(JSON.stringify(err));
    }
    return cb(null, res);
  };
}

// you're going to call this Lambda function from your code
exports.handle = function(event, context, handleCallback) {

  // allows for using callbacks as finish/error-handlers
  context.callbackWaitsForEmptyEventLoop = false;

  doSomeAsyncWork(event, context, doneFactory(handleCallback));
};
15
Jakub Koral

eh bien, si vous définissez 3 secondes dans la configuration de votre fonction, ce délai dépassera le temps à l'intérieur de votre code. Veillez donc à augmenter le délai d'attente de la configuration de votre fonction lambda et essayez à nouveau l'attente () et cela devrait fonctionner!

8
A.Elnaggar

J'ai rencontré le même problème. En fait, Lambda ne répond plus, par exemple:

  1. Analyse non valide json:

    exports.handler = function(event, context, callback)
    {
        var nonValidJson = "Not even Json";
        var jsonParse = JSON.parse(nonValidJson);
    
  2. Accès à la propriété de la variable non définie:

    exports.handler = function(event, context, callback)
    {
        var emptyObject = {};
        var value = emptyObject.Item.Key;
    
  3. Si la connexion mySql n'est pas fermée après avoir accédé à RDS, le délai d'attente Lambda expire et il devient alors non réactif.

Lorsque je dis insensible, il ne charge même pas, c'est-à-dire que la première impression dans le gestionnaire n'est pas imprimée et que Lambda se ferme à chaque exécution avec un délai d'expiration:

exports.handler = function(event, context, callback)
{
    console.log("Hello there");

C'est un bug, connu par l'équipe AWS depuis presque un an:
https://forums.aws.Amazon.com/thread.jspa?threadID=238434&tstart=

Malheureusement, le problème n'est toujours pas résolu. Après quelques tests, il a été révélé que Lambda essayait de redémarrer (recharger le conteneur?), Le temps manquait. Si vous définissez le délai d'expiration sur 10 secondes, Lambda commence à fonctionner après environ 4 secondes, puis se comporte normalement lors des prochaines exécutions. J'ai aussi essayé de jouer avec les réglages:

context.callbackWaitsForEmptyEventLoop = false;

et en plaçant tous les blocs "requis" dans le gestionnaire, rien ne fonctionnait vraiment. Le seul moyen d'empêcher Lambda de devenir mort consiste à définir un délai d'expiration plus long. Une correction à 10 devrait suffire amplement comme protection contre ce bogue.

4
Slava Elantsev

Dans la console Amazon AWS config, vous devez modifier le délai d'attente par défaut de 3 secondes à plus (maximum 5 min).

2
user2619052

Je devais simplement augmenter le délai d'attente et l'erreur s'est estompée. Je l'ai augmenté à 5 secondes. Cela me convenait car je n'allais pas utiliser ce Lambda en production.

0
Amaresh

Je pense que le problème vient de l'adresse IP mentionnée dans AWS RDS entrant/sortant.

Si vous testez pour le moment et que votre noeud.js travaille sur une idée locale et non sur AWS, procédez comme suit:

  1. Accédez à AWS RDS.

  2. Cliquez sur instance de base de données.

  3. Cliquez sur le nom de cette instance de base de données.
  4. Accédez à la section "Connexion" ci-dessous, où vous pouvez trouver les rôles du groupe de sécurité.
  5. Le type des groupes de sécurité sera entrant, sortant.
  6. Cliquez sur les deux un par un. Cela ouvrira une nouvelle fenêtre.
  7. Encore une fois, il y aura deux onglets pour les entrées et les sorties.
  8. Cliquez sur les deux l'un après l'autre.
  9. Cliquez sur "Modifier".
  10. Sélectionnez "Partout" au lieu de "Personnalisé". P.S. Répétez pour les deux entrants/sortants.

Tous ensemble.

0
Karan