skip to Main Content

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.

  1. If I do not specify reconnectStrategy and redis connection fail, the code trys to reconnect inifinitly.
  2. If redis connection fail with reconnectStrategy code, lambda gets to the catch section after 3 re-connections as expected.

2

Answers


  1. Chosen as BEST ANSWER

    version 4.3.0 solved the issue.


  2. 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:

    1. I have error handling for everything. with logs.
    2. after successful connect and before await redisClient.lRange('123', 0, -1); (I have "await"!!!!), I stop redis server locally and expect the reconnectStrategy to be triggered inside lRange function.
    3. I do NOT turn on redis server locally.
    4. Expected behavior: I am expecting the reconnectStrategy to fail eventually and propagate the error to the await redisClient.lRange('123', 0, -1); (await !!!!).
    5. Actual behavior: the error is not propagated to the catch of the await redisClient.lRange('123', 0, -1); and just thrown to the event loop and the process ends gracefully (exit code = 0 !!!! instead of 1").
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search