0
votes

My recursive lambda function stops when called with scheduled AWS events (also used with the cron job option). If I use lambda-dashboad or serverless framework for invoking - everything is OK. The duration of the lambda function is more than 6 hours, when called up through the event it runs from 15-30 minutes and then stops. Is there a difference between how to invoked the lambda function? Where can I find an explanation for this behavior?

LAMBDA-METHOD -> invokeLambda(lambdaname, payload) { // eslint-disable-line class-methods-use-this
    const req = {
      FunctionName: lambdaname,
      InvocationType: 'Event',
      Payload: JSON.stringify(payload),
    };

    const lambda = new aws.Lambda({
      region: 'us-east-1',
    });

    console.log(`[INFO - LAMBDA - ${lambdaname.toUpperCase()}] ${JSON.stringify(payload)}`);
    return lambda.invoke(req).promise();
  }
...
const createInstance = (Gapi, Parser, Lambda, Config) => {
  const gapi = new Gapi(Config);
  const parser = new Parser(gapi, Config);
  return new Lambda(gapi, parser, Config);
};
...
exports.sync_contacts = async (event, context) => {
    // create clear instance of class
    const Lambda = createInstance(GAPI, PARSER, LAMBDA, CONFIG); 
    // util for handle 5min limit lambda :use context.getRemainingTimeInMillis()
    const middleware = Ware(); 
    // return result off work after 5 min (worked 4.5 min then give 0.5 for refresh)
    const nextRefresh = await refresh(Lambda, middleware)(event, context);
    if (typeof nextRefresh === 'string') return nextRefresh;
    // recursive invoked
    if (nextRefresh.type === 'REFRESH') {
        return Lambda.invokeLambda(
            context.functionName,
            nextRefresh,
        );
    }
    // recursive invoked
    if (nextRefresh.type === 'DONE') {
        Lambda.token = nextRefresh.token;
        const [err, token] = await Lambda.tokenStep('NEXT');
        if (err) return err;
        if (token) {
            return Lambda.invokeLambda(
                context.functionName,
                { type: 'INIT', payload: { lastIndex: 0, token } },
            );
        }
    }
    // finish
    return '[LAMBDA - GLOBAL - DONE]';
};
1
I don't get your code since you are not directly using the official sdk, but yes there are actually 3 different ways of calling a Lambda: one is a dry run (no what you need), and the 2 others differ on being synchronous (RequestResponse) or asynchronous (Event). I have no idea if this could solve your problem but you could give it a try, who knows... - Cinn
And by the way the upper limit is 5 minutes (not 3 as mentioned in your code). There is a context method called getRemainingTimeInMillis() which can give you the remaining time to better handle the deadline - Cinn
I corrected the comments in the code - Anthony Andrews
Did you check the logs in CloudWatch? if yes can you provide it here so we can debug it with you? The problem of recursive function is that any failure will stop the entire execution, and it can be anything such as out of memory (very common), execution took too much time, IAM role does not have the required permissions etc. - Cinn
Also by default calling the callback (or using return in an AsyncFunction as you do) may not stop the Lambda execution if e.g a Promise is still in a pending state. You can change this behavior by setting context.callbackWaitsForEmptyEventLoop = false, more info here. - Cinn

1 Answers

0
votes

The problem was in the settings of the memorySize parameter. When I first run script the data was small and the default 128 MB was enough to complete the task. On next starting, the amount of data was large, that why I had to be increased to 512 MB. I hope someone will be useful given my experience on working with recursive lambda function.