AWS Lambda продолжает выполнение после обратного вызова - PullRequest
2 голосов
/ 23 декабря 2019

Я использую API Gateway + AWS Lambda для обработки запросов Slack API. Slack требует, чтобы функции Lambda отвечали 2XX в течение 3 секунд, поэтому мне нужно быстро отреагировать и затем запустить некоторые длительные операции с БД. Проблема заключается в том, что AWS Lambda либо (1) ждет, пока цикл событий не станет пустым, перед возвратом ответа в API Gateway, либо (2) возвращает ответ немедленно, когда вызывается функция callback, но затем сразу же останавливает выполнение Lambda идлительные операции с ним.

Чтение этого и других сообщений, кажется, что обычный способ сделать это состоит в том, чтобы иметь 2 лямбда-выражения: одно, которое немедленно отправляет ответ 2XX, а затем вызываетдругая лямбда для выполнения длительных операций. Это кажется хорошим, но мне интересно, можно ли это сделать всего одним лямбда-вызовом?

Вариант № 1 из этот превосходный ответ Марка Б, кажется, предполагает, что это возможно с помощью типа интеграции службы AWS. Но, следуя этим инструкциям для настройки интеграции службы AWS и установки заголовка типа вызова на «Событие», я все еще вижу, что выполнение Lambda замораживается сразу после запуска callback.

Мой маленький обработчик теста выглядит следующим образом. Я подозреваю, что Cloudwatch не регистрируется после запуска callback, поэтому у меня есть обработчик, который отправляет запрос ngrok через 5 секунд. Я ожидаю ответный вызов немедленно, а затем через 5 секунд я получаю запрос GET через ngrok.

const https = require('https');

exports.handler = function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;

    const options = {
      hostname: 'f3e7f2cc.ngrok.io',
      port: 443,
      path: '/',
      method: 'GET'
    };

    setTimeout(function() {
        console.log(options);
        const req = https.request(options, (res) => {
            console.log('statusCode:', res.statusCode);
            console.log('headers:', res.headers);
        });

        req.end();
    }, 5000);

    const end = new Date().toUTCString();
    callback(null, {body: "OK", timeEnd: end});
};

Однако я вижу, что это работает не так, как ожидалось. Я получаю немедленный callback ответ, но GET-запрос не получен через 5 секунд. Существуют ли дополнительные конфигурации, которые необходимо настроить, чтобы это заработало? Или я должен просто пойти с подходом 2 лямбда?

...