Вече разреших собствения си проблем и се надявам да мога да бъда полезен на някой, който се сблъсква с този проблем в бъдеще.
Има две основни съображения при свързване към база данни, както направих в кода по-горе от ламбда функция:
- Веднъж
context.succeed()
,context.fail()
илиcontext.done()
се нарича, AWS може да замрази всички процеси, които все още не са приключили. Това е причината AWS да регистрираConnection closed
при второто извикване към моята крайна точка на API — процесът беше замразен точно преди Redis да завърши затварянето, след това размразен при следващото извикване, в който момент продължи точно там, където спря, съобщавайки, че връзката е затворена. Извод:ако искате да затворите връзката си с базата данни, уверете се, че е напълно затворена преди наричате един от тези методи. Можете да направите това, като поставите обратно извикване в манипулатор на събитие, който се задейства от затваряне на връзка (.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
})
}
})
}
})
}
}
})
})
}
Това работи точно както трябва — и също така светка бързо.