Ответ 1
Теперь я решил свою проблему, и надеюсь, что я смогу помочь кому-то, испытывающему эту проблему в будущем.
При подключении к базе данных, как это было в приведенном выше коде, с помощью функции лямбда существует два основных момента:
- Как только
context.succeed()
,context.fail()
илиcontext.done()
вызывается, AWS может заморозить все процессы, которые еще не закончены. Это то, что заставляло AWS регистрироватьConnection closed
во втором вызове моей конечной точки API - процесс был заморожен как раз до того, как Redis завершил закрытие, затем оттаивал следующий вызов, после чего он продолжал идти туда, где он остановился, сообщая, что соединение было закрыто. Takeaway: если вы хотите закрыть соединение с базой данных, убедитесь, что он полностью закрыт, прежде чем вы вызываете один из этих методов. Вы можете сделать это, поместив обратный вызов в обработчик события, вызванный закрытием соединения (.on('end')
, в моем случае). - Если вы разделите свой код на отдельные файлы и
require
на них в верхней части каждого файла, как и я, Amazon будет кэшировать как можно больше из этих модулей в памяти. Если это вызывает проблемы, попробуйте переместить вызовыrequire()
внутри функции, а не вверху файла, а затем экспортировать эту функцию. Затем эти модули будут повторно импортированы всякий раз, когда функция будет запущена.
Здесь мой обновленный код. Обратите внимание, что я также добавил конфигурацию Redis в отдельный файл, поэтому я могу импортировать его в другие функции Lambda без дублирования кода.
Обработчик событий
'use strict'
const lib = require('../lib/related')
module.exports.handler = function (event, context) {
lib.respond(event, (err, res) => {
if (err) {
return context.fail(err)
} else {
return context.succeed(res)
}
})
}
Конфигурация Redis
module.exports = () => {
const redis = require('redis')
const jsonify = require('redis-jsonify')
const redisOptions = {
host: process.env.REDIS_URL,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASS
}
return jsonify(redis.createClient(redisOptions))
}
Функция
'use strict'
const rt = require('./ritetag')
module.exports.respond = function (event, callback) {
const redis = require('./redis')()
const tag = event.hashtag.replace(/^#/, '')
const key = 'related:' + tag
let error, response
redis.on('end', () => {
callback(error, response)
})
redis.on('ready', function () {
redis.get(key, (err, res) => {
if (err) {
redis.quit(() => {
error = err
})
} else {
if (res) {
// Tag is found in Redis, so send results directly.
redis.quit(() => {
response = res
})
} else {
// Tag is not yet in Redis, so query Ritetag.
rt.hashtagDirectory(tag, (err, res) => {
if (err) {
redis.quit(() => {
error = err
})
} else {
redis.set(key, res, (err) => {
if (err) {
redis.quit(() => {
error = err
})
} else {
redis.quit(() => {
response = res
})
}
})
}
})
}
}
})
})
}
Это работает точно так же, как и должно быть - и оно быстро пылает.