I have upgraded to redis 4.2.0 with the following lambda :
import * as redis from "redis";
export const handler = async (
event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback
) => {
try {
console.log(`Lambda triggered with event: ${JSON.stringify(event)}`);
context.callbackWaitsForEmptyEventLoop = false;
const redisClient = redis.createClient({
socket: {
host: '127.0.0.1',
port: 6379,
reconnectStrategy: function (retriesAttemptedSoFar: number): number | Error {
if (retriesAttemptedSoFar > 3) {
// End reconnecting with error
return new Error(`Redis retry attempt=${retriesAttemptedSoFar}`);
}
console.info(` try reconnect after ${Math.min(retriesAttemptedSoFar * 10, 30)}ms`);
// reconnect after
return Math.min(retriesAttemptedSoFar * 10, 30);
}
},
});
redisClient.on('ready', () => {
console.log(`Got "ready" event from Redis. Connection established.`);
});
redisClient.on('connect', () => {
console.log(`Got "connect" event from Redis. Stream is connected to the server`);
});
redisClient.on('error', (err) => {
console.log(`Got an ERROR from Redis. Details: ${err.message}`);
});
await redisClient.connect();
let serverStates : string[] = [];
const MAX_RETRIES = 3;
let i = 0;
while (i < MAX_RETRIES) {
try {
serverStates = await redisClient.lRange('123', 0, -1);
} catch (e) {
i++;
const logMessage = i < MAX_RETRIES ?
`attempt ${i}: Failed to store message. Trying again...` :
`attempt ${i}: Failed to store message. All attempts failed`;
console.warn(logMessage);
await new Promise(resolve => setTimeout(resolve, 10));
}
}
if (i >= MAX_RETRIES) {
throw new Error('Exceeded Max Attempts to store message in Redis');
}
console.log(`ServerStates: ${JSON.stringify(serverStates)}`);
console.log(`${JSON.stringify(event)} Lambda finished successfully`);
callback(null, {
statusCode: 200,
body: 'theResult'
});
} catch (e) {
const error = e as Error;
console.error(`Lambda execution failed. Got error: ${error.message}`);
callback(error);
}
}
If I do not get exception from redis, all works.
- If I do not specify reconnectStrategy and redis connection fail, the code trys to reconnect inifinitly.
- If redis connection fail with reconnectStrategy code, lambda gets to the catch section after 3 re-connections as expected.
2
Answers
version 4.3.0 solved the issue.
After talking privatly with @Ida on the phone, here is a summary of the error and a possible explanation of the bug (in redis library):
Summary of the problem:
await redisClient.lRange('123', 0, -1);
(I have "await"!!!!), I stop redis server locally and expect the reconnectStrategy to be triggered inside lRange function.await redisClient.lRange('123', 0, -1);
(await !!!!).await redisClient.lRange('123', 0, -1);
and just thrown to the event loop and the process ends gracefully (exit code = 0 !!!! instead of 1").