Nyní jsem vyřešil svůj vlastní problém a doufám, že budu moci být nápomocný někomu, kdo bude mít tento problém v budoucnu.
Při připojování k databázi, jako jsem to udělal ve výše uvedeném kódu z funkce Lambda, jsou dvě hlavní úvahy:
- Jakmile
context.succeed()
,context.fail()
nebocontext.done()
AWS může zmrazit všechny procesy, které ještě neskončily. To způsobilo, že AWS zaprotokolovaloConnection closed
při druhém volání do mého koncového bodu API – proces byl zmrazen těsně předtím, než Redis dokončil uzavření, pak se rozmrazil při dalším volání, v kterémžto okamžiku pokračoval přesně tam, kde skončil, a oznámil, že připojení bylo uzavřeno. S sebou:pokud chcete ukončit připojení k databázi, ujistěte se, že je úplně uzavřeno před zavoláte jednu z těchto metod. Můžete to udělat vložením zpětného volání do obslužné rutiny události, která je spuštěna uzavřením připojení (.on('end')
, v mém případě). - Pokud kód rozdělíte do samostatných souborů a
require
je v horní části každého souboru, stejně jako já, Amazon uloží do mezipaměti co nejvíce těchto modulů. Pokud to způsobuje problémy, zkuste přesunoutrequire()
volá uvnitř funkce namísto v horní části souboru a poté tuto funkci exportuje. Tyto moduly budou poté znovu importovány při každém spuštění funkce.
Zde je můj aktualizovaný kód. Všimněte si, že jsem také vložil svou konfiguraci Redis do samostatného souboru, takže ji mohu importovat do jiných funkcí Lambda bez duplikace kódu.
Obsluha události
'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)
}
})
}
Konfigurace 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))
}
Funkce
'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
})
}
})
}
})
}
}
})
})
}
Funguje to přesně tak, jak má – a také to rychle letí.