узел 8.10 + Запрос заставляет AWS лямбда охватывать результат за два запроса - PullRequest
0 голосов
/ 24 апреля 2018

отредактировано для добавления дополнительной информации

У меня серьезные проблемы с любой библиотекой, которая использует «запрос» при запуске в AWS Lambda. Запуск одного и того же кода в той же версии Node локально работает нормально.

Я перепробовал все, что предлагается в этом выпуске https://github.com/request/request/issues/2047

Я также попробовал лямбда-форум AWS, службу поддержки Amazon, канал Slack и репо с обещаниями и запросами. Сам запрос просто направляет запросы сюда.

Я не могу опубликовать полный пример здесь, так как моя функция имеет 18 файлов, 8 пакетов, все со своими собственными подпакетами. Тем не менее, он значительно ниже максимального размера кода Lambda Это именно тот код, который я запускаю в самой функции:

'PodcastInvocationIntent': function () {
        feedparser.parse("http://feeds.soundcloud.com/users/soundcloud:users:238643239/sounds.rss").then(items => {
            const now = new Date();
            console.log(`within feedparser and got item1  of ${items[0].title} at ${now}`);
        }).catch(err => {
            console.log(`Caught an error in checking - ${err}`);
        });
    },

Я вызываю функцию, которая просто вызывает действительный, быстро реагирующий подкаст. Примечание: я могу убедиться, что означает «холодный старт», выполнив ask deploy -t lamba.

START RequestId: dcae5bc2-4883-11e8-a386-853cdfb729cc Version: $LATEST
2018-04-25T12:26:22.593Z    dcae5bc2-4883-11e8-a386-853cdfb729cc    in _MAINMENU_MODE and caught PodcastInvocationIntent
END RequestId: dcae5bc2-4883-11e8-a386-853cdfb729cc
REPORT RequestId: dcae5bc2-4883-11e8-a386-853cdfb729cc  Duration: 129.95 ms Billed Duration: 200 ms     Memory Size: 1024 MB    Max Memory Used: 48 MB  

Если я позвоню позже, я получу остальную часть первого запроса. Обратите внимание, что RequestId для результатов feedparser совпадает с первым вызовом, заканчивающимся 853cdfb729cc, «перенесенным» на идентификатор запроса почти минуту спустя, 171032bc3aa8

START RequestId: f6dcc8de-4883-11e8-be3e-171032bc3aa8 Version: $LATEST
2018-04-25T12:27:05.605Z    dcae5bc2-4883-11e8-a386-853cdfb729cc    within feedparser and got item1 of Episode 020 - Building Community in the Era of Voice at Wed Apr 25 2018 12:27:05 GMT+0000 (UTC)
2018-04-25T12:27:05.750Z    f6dcc8de-4883-11e8-be3e-171032bc3aa8    in _MAINMENU_MODE and caught PodcastInvocationIntent
END RequestId: f6dcc8de-4883-11e8-be3e-171032bc3aa8
REPORT RequestId: f6dcc8de-4883-11e8-be3e-171032bc3aa8  Duration: 327.94 ms Billed Duration: 400 ms     Memory Size: 1024 MB    Max Memory Used: 54 MB  

Обратите внимание, что это почти через минуту - мой тайм-аут лямбды установлен на 6 секунд, а мой тайм-аут запроса установлен на 3 секунды, и сайт отвечает в течение 300 мс. И вы можете увидеть из заголовков, отправленных сервером, что то, что регистрируется, определенно является первым запросом.

Другое дело - вот несколько резюме запросов, с которых он работал во второй раз:

REPORT RequestId: 55fe3685-487f-11e8-9d8a-7f110e92019c Duration: 29.75 ms  Billed Duration: 100 ms  Memory Size: 1024 MB Max Memory Used: 55 MB < fail 
REPORT RequestId: 6b657de4-487f-11e8-b3d9-775cb704cd69 Duration: 119.94 ms Billed Duration: 200 ms  Memory Size: 1024 MB Max Memory Used: 55 MB < OK 

REPORT RequestId: 79c7e5ef-487f-11e8-a6be-039c7c5578d1 Duration: 18.75 ms  Billed Duration: 100 ms  Memory Size: 1024 MB Max Memory Used: 65 MB < fail 
REPORT RequestId: 95b42e1f-487f-11e8-863b-1bf45c029658 Duration: 122.49 ms Billed Duration: 200 ms  Memory Size: 1024 MB Max Memory Used: 65 MB < OK 

Обратите внимание, что в первый раз запрос заканчивается через 18 или 29 мс, но сервер подкастов НИКОГДА не отвечает быстрее, чем 55 мс (максимум 300 мс). Но чтобы быть ясным, я пробовал несколько подкастов на разных серверах разных размеров.

(Понятия не имею, почему вторые два больше на 10 Мб - тот же код!)

Это имеет смысл! Есть идеи? Узел 8.10 запрос 2.85.0 alexa-sdk 1.0.25, загружает запасную память на Lambda, не выходя за пределы.

Я пробовал запрос, запрос-обещание и обещание feedparser, и все они показывают одинаковые симптомы. Спасибо.

1 Ответ

0 голосов
/ 25 апреля 2018

Наконец-то нашел ответ, почти случайно. Опасность копирования примеров кода!

tl; dr this.emit(':saveState', true); винты с библиотекой запросов!

У меня МНОГО состояний, лиц, управляющих государством, и намерений. Каждое намерение должно быть доступно горизонтально из любого состояния. Нельзя делать с дублированием каждого намерения в каждом штате, так что ...

В каждом состоянии у меня есть определенные обработчики для этого состояния, и необработанный захватывает все остальное и передает его в genericIntentHandler. Затем он перенаправляет его в правильное состояние и обработчик. Как это:

 'Unhandled': function () {
            console.log(`in ${this.attributes.STATE} and caught ${this.event.request.intent.name}`);
            GIH.genericIntentHandlers.call(this);
        },

А потом отдельно:

function genericIntentHandlers() {
    if (this.event.request.type === 'IntentRequest') {
        const intentName = this.event.request.intent.name;
        console.log(`in genericIntentHandlers redirect function with ${intentName}`);
        if (genericHandlers.hasOwnProperty(intentName)) { // true
            genericHandlers[intentName].call(this);
        } else {
            this.response.speak("I didn't understand that. Try main main or help if you're stuck.").listen("reprompt");
            this.emit(':responseReady');
        }
    } else {
        console.log(`in genericIntentHandlers redirect function with LaunchRequest`);
        genericHandlers['LaunchRequest'].call(this);
    }
}


const genericHandlers = {
    'PodcastInvocationIntent': function () {
        this.handler.state = constants.states.POD_MODE;
        // this.emit(':saveState', true); // this is what was screwing it!
        this.emitWithState('PodcastInvocationIntent');
    }
// plus every single state that exists anywhere. Like a lookup table.
}

и в обработчике состояний POD_MODE:

'PodcastInvocationIntent': function () {
            feedparser.parse("http://feeds.soundcloud.com/users/soundcloud:users:238643239/sounds.rss").then(items => {
                const now = new Date();
                console.log(`within feedparser and got item1  of ${items[0].title} at ${now}`);
                //console.log(`within feedparser and got items of ${JSON.stringify(items)}`);
            }).catch(err => {
                console.log(`Caught an error in checking - ${err}`);
            });
        },

Итак, чтобы уточнить, и после большого повторного тестирования:

В нормальном ходе событий испускание this.emit(':saveState', true); не имеет значения, ЕСЛИ НЕ использует библиотеку, которая использует библиотеку запросов, и в этом случае кажется, что она «разделяет» запрос на два лямбда-экземпляра. Да, знаю. Insanity.

Это оставляет два вопроса: почему? И, конечно же, это делает этот бит документации неверным?

Когда генерируется какое-либо из ответных событий: ask,: tell,: askWithCard и т. Д. Метод lambda context.succeed () вызывается, если разработчик не передает функцию обратного вызова, которая немедленно останавливает обработку дальнейших действий. фоновые задачи. Любые асинхронные задания, которые все еще не завершены, не будут выполнены, и любые строки кода ниже оператора emit ответа не будут выполнены. Это не относится к неотвечающим событиям, таким как: saveState.

Итак, если это неотвечающее событие, почему оно мешает?

Во всяком случае, это, как говорится, это так. И через неделю я никогда не вернусь, но с огромной благодарностью тем, кто помог мне на этом пути.

...