When calling Lambda from AWS Lambda, the calling Lambda finishes processing without waiting for a response from the calling Lambda.

Asked 2 years ago, Updated 2 years ago, 93 views

Polly creates MP3 and then uploads it to S3 and calls Lambda back to the URL from another Lambda, but the caller Lambda completes it first without waiting for the caller's response.The MP3 creation by the calling Lambda is now complete after the calling party completes.

How do I wait for Lambda's response before completing Lambda's response?

■ Calling Lambda

var lambda=new AWS.Lambda({apiVersion:'2015-03-31'})
exports.handler=function(event, context, callback){
    res=invokeCreateMp3()
    console.log(res) // undefined
}

function invokeCreateMp3(name,sec){
    lambda.invoke({
        FunctionName: 'create_mp3_for_timer',
        InvocationType: 'RequestResponse',
        Payload: '{"name":"kana", "sec":3}',
    }, function(error,data){
        if(error){
            console.log("error:" + error)
        } else{
            console.log("response:" + data)
        }
    });
}

■ Called Lambda

var poll = new AWS.Polly ({apiVersion:'2016-06-10'});
vars3 = new AWS.S3 ({apiVersion:'2006-03-01'});

exports.handler=function(event, context, callback){
    varurl=createMp3 (event.name, event.sec);
    varres = {
        "statusCode": 200,
        "headers": { "Additional-Headr1": "1234"},
        "body" : JSON.stringify({"response" : "response", "event" : event, "url" : url },
    };

    callback(null,res);
};

function createMp3(name,sec){
    varsml='<speak><break time='+sec+'s"/>'+name+' timer is over.</speak>';
    var bucket = 'mp3_book';
    varkey = name + '_' + sec + 's.mp3';
    var url = 'https://s3-ap-northeast-1.amazonaws.com/' + bucket + '/' + key;

    let speechParams={
        OutputFormat: 'mp3',
        VoiceId: 'Mizuki',
        Text: ssml,
        SampleRate: '22050',
        TextType: 'ssml'
    };


    poly.synthesizeSpeech(speechParams).promise().then(data)=>{
        console.log(data); // successful response
        // Parameters for putting to s3
        vars3Params = {
            ACLs: 'public-read', // S3 privileges
            Bucket: buket,
            Key: key,
            ContentType: 'audio/mp3',
            Body: Get new Buffer (data.AudioStream) // AudioStream
        };
        // put to s3
        s3.putObject(s3Params,(err)=>{
            if(err){
                console.log(err);
            } else{
                console.log('Success');
            }
        });
    }, (error) = > {
        console.log("Failure!", error);
    });
    return url;
}

aws lambda amazon-s3

2022-09-30 21:29

2 Answers

The caller does not appear to be waiting for a callback implementation.
I haven't been able to verify the operation, but I think I can do it synchronously if I fix it like this.

var lambda=new AWS.Lambda({apiVersion:'2015-03-31'})
exports.handler=async function(event, context, callback) {
    res=wait inviteCreateMp3()
    console.log(res) // undefined
}

async function invokeCreateMp3(name,sec){
    try{
        const data = wait lambda.invoke({
            FunctionName: 'create_mp3_for_timer',
            InvocationType: 'RequestResponse',
            Payload: '{"name":"kana", "sec":3}',
        }).promise();
        console.log("response:"+data);
        return data;
    } catch(error){
        console.log("error:"+error);
        return error;
    }
}


2022-09-30 21:29

I'm not familiar with nodejs, so I may have removed it, but I think InvokeCreateMp3 works asynchronously, so I think I need to wait for it to end by returning a promise.
Similarly, createMP3 part.

I think it is necessary to use promote for putObject.


2022-09-30 21:29

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.