

PollyでMP3を作成してからS3にアップロードし、URLを返すLambdaを、別のLambdaから呼び出しているのですが、呼び出し先のレスポンスを待たずに呼び出し元のLambdaが先に完了してしまします。呼び出し先のLambdaによるMP3作成は、呼び出し元が完了後に完了する動きになってしまっています。

呼び出し先のLambdaのレスポンスを待ってから、呼び出し元のLambdaを完了させるにはどうすればよいでしょうか。

■呼び出し元のLambda

[code]

    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)
            }
        });
    }
    
[/code]

■呼び出し先のLambda

[code]

    var polly = new AWS.Polly({apiVersion: '2016-06-10'});
    var s3 = new AWS.S3({apiVersion: '2006-03-01'});
    
    exports.handler = function(event, context, callback) {
        var url = createMp3(event.name, event.sec);
        var res = {
            "statusCode": 200,
            "headers": { "Additional-Headr1": "1234" },
            "body": JSON.stringify({"response":"response", "event":event, "url":url}),
        };
    
        callback(null, res);
    };
    
    function createMp3(name, sec) {
        var ssml = '<speak><break time="' + sec +'s" />' + name +'タイマーは終わりです。</speak>';
        var buket = 'mp3_buket';
        var key = name + '_' + sec + 's.mp3';
        var url = 'https://s3-ap-northeast-1.amazonaws.com/' + buket + '/' + key;
    
        let speechParams = {
            OutputFormat: 'mp3',
            VoiceId: 'Mizuki',
            Text: ssml,
            SampleRate: '22050',
            TextType: 'ssml'
        };
    
    
        polly.synthesizeSpeech(speechParams).promise().then((data) => {
            console.log(data);           // successful response
            // s3にPutする用のパラメータ
            var s3Params = {
                ACL: 'public-read', //S3権限
                Bucket: buket,
                Key: key,
                ContentType: 'audio/mp3',
                Body: new Buffer(data.AudioStream) // AudioStreamの取得
            };
            // s3にputする
            s3.putObject(s3Params, (err) => {
                if (err) {
                    console.log(err);
                } else {
                    console.log('Success');
                }
            });
        }, (error) => {
            console.log("Failure!", error);
        });
        return url;
    }
    
[/code]


CC BY-SA 3.0
2018-01-30T02:56:53.430
41314
2022-10-26T14:46:58.760
2022-10-26T14:46:58.760
19110
27202
question
aws amazon-s3 aws-lambda
AWSのLambdaからLambdaを呼び出したときに、呼び出し先のLambdaからのレスポンスを待たずに呼び出し元のLambdaが処理終了してしまう


nodejsにあまり詳しくないので、外しているかもしれませんが、まずinvokeCreateMp3は非同期で動作すると思うので、promiseを返すなどして終了待機をする必要があるのでは？  
同様にcreateMP3の部分も。

putObjectもpromiseを使う必要があるかと思います。


CC BY-SA 4.0
2019-06-01T09:06:57.123
55428
2019-06-01T09:06:57.123
34547
41314
answer


呼び出し元がコールバックを待つ実装になっていないようです。  
動作確認まではできていないのですが、こんな感じに修正すれば同期的に実行できるのではないでしょうか。

[code]

    var lambda = new AWS.Lambda({apiVersion: '2015-03-31'})
    exports.handler = async function(event, context, callback){
        res = await invokeCreateMp3()
        console.log(res) //undefinedになる
    }
    
    async function invokeCreateMp3(name, sec) {
        try {
            const data = await 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;
        }
    }
    
[/code]


CC BY-SA 4.0
2020-07-22T02:59:17.920
68807
2020-07-22T02:59:17.920
70
41314
answer