Sekarang saya telah memecahkan masalah saya sendiri, dan saya harap saya dapat membantu seseorang yang mengalami masalah ini di masa mendatang.
Ada dua pertimbangan utama saat menghubungkan ke database seperti yang saya lakukan pada kode di atas dari fungsi Lambda:
- Sekali
context.succeed()
,context.fail()
, ataucontext.done()
dipanggil, AWS dapat membekukan proses apa pun yang belum selesai. Inilah yang menyebabkan AWS mencatatConnection closed
pada panggilan kedua ke titik akhir API saya—prosesnya dibekukan tepat sebelum Redis selesai ditutup, lalu dicairkan pada panggilan berikutnya, di mana titik itu berlanjut tepat di tempat terakhirnya, melaporkan bahwa koneksi ditutup. Takeaway:jika Anda ingin menutup koneksi database Anda, pastikan koneksi ditutup sepenuhnya sebelum Anda memanggil salah satu metode itu. Anda dapat melakukan ini dengan menempatkan panggilan balik di pengendali peristiwa yang dipicu oleh penutupan koneksi (.on('end')
, dalam kasus saya). - Jika Anda membagi kode menjadi file terpisah dan
require
mereka di bagian atas setiap file, seperti yang saya lakukan, Amazon akan menyimpan sebanyak mungkin modul tersebut di memori. Jika itu menyebabkan masalah, coba pindahkanrequire()
memanggil di dalam fungsi alih-alih di bagian atas file, lalu mengekspor fungsi itu. Modul tersebut kemudian akan diimpor ulang setiap kali fungsi dijalankan.
Ini kode saya yang diperbarui. Perhatikan bahwa saya juga telah menempatkan konfigurasi Redis ke dalam file terpisah, sehingga saya dapat mengimpornya ke fungsi Lambda lain tanpa menduplikasi kode.
Penangan Acara
'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)
}
})
}
Konfigurasi 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))
}
Fungsi
'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
})
}
})
}
})
}
}
})
})
}
Ini berfungsi sebagaimana mestinya—dan juga sangat cepat.