Подключение к базе данных MySql из функции AWS Lambda с помощью Node.js, без обратного вызова подключения

Я пытаюсь подключить внешний (не AWS) сервер MySql из функции AWS Lambda, написанной на Node.js, с использованием среды nodejs14.x, но обратный вызов connect() не вызывается.

Я борюсь с этой проблемой уже несколько дней, есть много ссылок на похожие проблемы, но я действительно перепробовал все возможные варианты решений, которые нашел.

Я развертываю с помощью SAM и тестирую как на локальной машине, так и на реальном AWS.

Вот пример кода помощника лямбда

    const mysql = require('mysql');

    exports.helloFromLambdaHandler = async () => {

    const message = 'Hello from Lambda!';

    console.info(`${message}`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.info("Doing createConnection");
    const connection = mysql.createConnection({
        /* my connection data */
      });
    
    console.info("Doing connect");
    connection.connect( (err) => {
        console.info("Inside connection callback");
        console.info('connected as id ' + connection.threadId);

        if (!err) {
          console.info("DB connected, thread id is "  + connection.threadId);
          console.info("Doing query");

          connection.query(sql, values, (err, result, values) => {
            console.info("Inside query callback");
            if (!err) {
              console.info("Query ok!");
              console.info(result);
              connection.end();
            } else {
              console.info("Error executing query: " + err.message);
            }       
          });
          
        } else {
          console.info("Error connecting db: "+ err.message);
        }
      });

    console.info ("Returning...");
    return message;
}

Журнал

Hello from Lambda!
Doing createConnection
Doing connect
Returning...

Ожидаемое поведение состоит в том, что после «Returning ...» я должен увидеть журнал «Обратный вызов внутреннего соединения», затем «Обратный вызов внутреннего запроса», а затем «Запрос в порядке!».

Вместо этого обратный вызов connect() не вызывается.

Я знаю, что могу вызвать query() напрямую, пропуская connect(), но при этом я сталкиваюсь с той же проблемой.

Есть подсказка?

Спасибо!

РЕШЕНИЕ

Как следует из принятого ответа, возврат обещания - это решение, позволяющее Node завершить всю очередь. К сожалению, насколько я понимаю, невозможно завершить Lambda и оставить ее работать в фоновом режиме безопасным способом.

Я исследую альтернативные решения, такие как:

  • Библиотека mysql2, которая изначально поддерживает обещания
  • бессерверный MySQL npm пакет, который обрабатывает общие соединения db

Ниже работающего демонстрационного кода

const mysql = require('mysql');

exports.helloFromLambdaHandler = async (event, context) => {

    const message = 'Hello from Lambda!';

    console.info(`${message}`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.info("Doing createConnection");
    const connection = mysql.createConnection({
        /* my connection data */
      });
    
    console.info("Doing query");

    const promise = new Promise( (resolve, reject) => {
        connection.query(sql, values, (err, result, values) => {
        console.info("Inside query callback");
        if (!err) {
            console.info("Query ok!");
            console.info(result);
            connection.end();
            resolve(message);
        } else {
            console.info("Error executing query: " + err.message);
            reject(err);
        }       
        });
    });

    console.info ("Returning...");
    return promise;
}

Вообще говоря: после того, как вы вернетесь из лямбды, лямбда будет выполнена, она не выполняет никакой дальнейшей работы, ее память / диск заморожены до следующего вызова лямбды.

luk2302 06.04.2021 12:27

Как указал Марцин, это поведение связано с объявлением обработчика async! Удаление этого ключевого слова позволило обрабатывать очередь узлов после возврата! :)

Ascanio Orlandini 06.04.2021 13:05
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
2
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете асинхронный обработчик, поэтому ваша функция, вероятно, завершится до того, как ваш connect() сможет выполнить.

Чтобы попытаться решить проблему, вы можете использовать Promise, как показано в Документы AWS.

Спасибо! Простое удаление ключевого слова async в объявлении обработчика позволило обработать всю мою очередь узлов, как ожидалось !! Теперь я выясню, действительно ли мне нужен асинхронный хендер или нет, и я буду следить за ним соответствующим образом!

Ascanio Orlandini 06.04.2021 13:07

Подробное объяснение проблемы, с которой я столкнулся, можно найти по ссылке ниже, еще раз спасибо за то, что указали мне в правильном направлении !!! levelup.gitconnected.com/…

Ascanio Orlandini 06.04.2021 13:36

Другие вопросы по теме