Teraz rozwiązałem swój własny problem i mam nadzieję, że będę mógł pomóc komuś, kto ma ten problem w przyszłości.
Podczas łączenia się z bazą danych, tak jak to zrobiłem w powyższym kodzie z funkcji Lambda, należy wziąć pod uwagę dwie główne kwestie:
- Raz
context.succeed()
,context.fail()
lubcontext.done()
jest wywoływana, AWS może zamrozić wszystkie procesy, które jeszcze się nie zakończyły. To właśnie powodowało, że AWS rejestrowałConnection closed
przy drugim wywołaniu mojego punktu końcowego API — proces został zamrożony tuż przed zakończeniem zamykania Redis, a następnie rozmrożony przy następnym wywołaniu, w którym to momencie kontynuował dokładnie tam, gdzie został przerwany, zgłaszając, że połączenie zostało zamknięte. Na wynos:jeśli chcesz zamknąć połączenie z bazą danych, upewnij się, że jest ono całkowicie zamknięte przed nazywasz jedną z tych metod. Możesz to zrobić, umieszczając wywołanie zwrotne w module obsługi zdarzeń, który jest wyzwalany przez zamknięcie połączenia (.on('end')
, w moim przypadku). - Jeśli podzielisz kod na osobne pliki i
require
je na górze każdego pliku, tak jak ja, Amazon zapisze w pamięci tyle modułów, ile to możliwe. Jeśli to powoduje problemy, spróbuj przenieśćrequire()
wywołuje wewnątrz funkcji zamiast na górze pliku, a następnie eksportuje tę funkcję. Te moduły zostaną następnie ponownie zaimportowane za każdym razem, gdy funkcja zostanie uruchomiona.
Oto mój zaktualizowany kod. Zauważ, że umieściłem również moją konfigurację Redis w osobnym pliku, więc mogę ją zaimportować do innych funkcji Lambda bez duplikowania kodu.
Obsługa zdarzeń
'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)
}
})
}
Konfiguracja 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))
}
Funkcja
'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
})
}
})
}
})
}
}
})
})
}
Działa to dokładnie tak, jak powinno — i jest też niesamowicie szybkie.