Jeg har nu løst mit eget problem, og jeg håber, jeg kan være til hjælp for nogen, der oplever dette problem i fremtiden.
Der er to vigtige overvejelser, når du opretter forbindelse til en database, som jeg gjorde i koden ovenfor fra en Lambda-funktion:
- Når
context.succeed()
,context.fail()
, ellercontext.done()
kaldes, kan AWS fryse alle processer, der ikke er afsluttet endnu. Det er det, der fik AWS til at loggeConnection closed
ved det andet kald til mit API-slutpunkt – processen blev fastfrosset lige før Redis afsluttede med at lukke, og tøede derefter op ved det næste kald, hvorefter den fortsatte lige hvor den slap og rapporterede, at forbindelsen var lukket. Takeaway:Hvis du vil lukke din databaseforbindelse, skal du sørge for, at den er helt lukket før du kalder en af de metoder. Du kan gøre dette ved at placere et tilbagekald i en hændelseshandler, der udløses af en forbindelse, der lukkes (.on('end')
, i mit tilfælde). - Hvis du deler din kode op i separate filer og
require
dem øverst i hver fil, ligesom jeg gjorde, vil Amazon cache så mange af disse moduler som muligt i hukommelsen. Hvis det giver problemer, så prøv at flytterequire()
kalder inde i en funktion i stedet for i toppen af filen, og eksporterer derefter denne funktion. Disse moduler vil derefter blive genimporteret, hver gang funktionen køres.
Her er min opdaterede kode. Bemærk, at jeg også har lagt min Redis-konfiguration i en separat fil, så jeg kan importere den til andre Lambda-funktioner uden at duplikere kode.
Begivenhedshåndteringen
'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-konfiguration
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))
}
Funktionen
'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
})
}
})
}
})
}
}
})
})
}
Dette fungerer præcis, som det skal – og det er også lynhurtigt.