6

My Scenario

I'm trying to utilize the global scope of Node.js to initialize a database connection once, and use the initialized connection when the lambda function is invoked.

This can save a lot of resources and time, as opening a DB connection is a lengthy process:

// Global scope: Runs only once

const redis = require('redis');

const client = redis.createClient({ <HOST>, <PORT> });

// Function scope: runs per invocation
exports.handler = (event, context, callback) => {
     do-something-with-redis
};

My Problem

Some common connection errors may occur

  • Uninitialized connection: Since Node.js is asynchronous, the function may start executing code before redis.create returns, hence using an uninitialized connection.
  • Timeout: If the connection attempt times out for some reason, the function will have an erroneous handler.
  • Runtime error: If a connection error happens during code execution, following invocation will have an erroneous handler.

My Question

What's the proper way to overcome errors (initialization, timeout and runtime) of a global Redis connection used by an AWS Lambda function?

Adam Matan
  • 128,757
  • 147
  • 397
  • 562
  • It seems that commands are queued when disconnected and replayed once (re)connected. Otherwise, you could use the event emitted by the `client`. https://github.com/NodeRedis/node_redis#connection-and-other-events – Alexis N-o Jan 10 '18 at 10:00

1 Answers1

0

Lambda functions were designed to be stateless, so I don't know if there is one best answer to this. There's a really helpful GitHub comment about Lambda and RDS, but it mostly applies. It mentions that the answer depends on how many requests it'll be making.

Regardless, this SO answer is more or less how I would do it; though I prefer a Promise-based API for the Redis library. The author handles the Uninitialized Connection issue by using callbacks to wait until the connection is opened before trying to use the connection. The other two issues you raise are also handled in that SO answer. Basically: if (err) callback(err).

I mean, given the GitHub comment message is from support at AWS, you need to make a connection inside the handler, so you may as well only do it there until you're sure you need the perf boost.

I realize this doesn't exactly answer the question, but the question has been open for a few days now and I'm curious. And there's nothing like being wrong on the internet to find out the right answer...

Sam H.
  • 4,091
  • 3
  • 26
  • 34