Я пытаюсь создать API для одностраничного веб-приложения, используя AWS Lambda и Сервер без сервера. Я хочу использовать Redis Cloud для хранения, в основном для сочетания скорости и сохранения данных. В будущем я могу использовать больше возможностей Redis Cloud, поэтому я бы предпочел не использовать ElastiCache для этого. Мой экземпляр Redis Cloud работает в той же области AWS, что и моя функция.
У меня есть функция с именем related
, которая принимает хэштег из запроса GET в конечную точку API и проверяет, есть ли в нем запись в базе данных. Если он там, он должен немедленно вернуть результаты. Если нет, он должен запросить RiteTag, записать результаты в Redis, а затем вернуть результаты пользователю.
Я новичок в этом, поэтому я, вероятно, делаю что-то восхитительно наивное. Здесь обработчик события:
'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)
}
})
}
Здесь ../lib/related.js
файл:
var redis = require('redis')
var jsonify = require('redis-jsonify')
var rt = require('./ritetag')
var redisOptions = {
host: process.env.REDIS_URL,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASS
}
var client = jsonify(redis.createClient(redisOptions))
module.exports.respond = function (event, callback) {
var tag = event.hashtag.replace(/^#/, '')
var key = 'related:' + tag
client.on('connect', () => {
console.log('Connected:', client.connected)
})
client.on('end', () => {
console.log('Connection closed.')
})
client.on('ready', function () {
client.get(key, (err, res) => {
if (err) {
client.quit()
callback(err)
} else {
if (res) {
// Tag is found in Redis, so send results directly.
client.quit()
callback(null, res)
} else {
// Tag is not yet in Redis, so query Ritetag.
rt.hashtagDirectory(tag, (err, res) => {
if (err) {
client.quit()
callback(err)
} else {
client.set(key, res, (err) => {
if (err) {
callback(err)
} else {
client.quit()
callback(null, res)
}
})
}
})
}
}
})
})
}
Все это работает, как ожидалось, до определенной степени. Если я запустил функцию локально (используя sls function run related
), у меня нет никаких проблем, из-за чего теги считываются и записываются в базу данных Redis, как и должно быть. Однако, когда я его развертываю (используя sls dash deploy
), он работает при первом запуске после развертывания и затем перестает работать. Все последующие попытки запустить его просто возвращают null
в браузер (или Postman, или curl, или веб-приложение). Это верно независимо от того, используется ли тег, который я использую для тестирования, в базе данных или нет. Если я затем повторно развернусь, не внося никаких изменений в функцию, она снова будет работать один раз.
На моем локальном компьютере функция сначала регистрирует Connected: true
на консоли, затем результаты запроса, затем Connection closed.
В AWS он регистрирует Connected: true
, затем результаты запроса и его. Во втором запуске он записывает Connection closed.
и ничего больше. На третьем и последующих последующих сеансах он ничего не записывает. Ни одна среда не сообщает о каких-либо ошибках.
Кажется довольно очевидным, что проблема связана с подключением к Redis. Если я не закрываю его в обратных вызовах, то последующие попытки вызвать функцию просто тайм-аут. Я также пытался использовать redis.unref
вместо redis.quit
, но это, похоже, не имело никакого значения.
Любая помощь будет принята с благодарностью.