Java lambda返回后AWS转录作业未完成

Java lambda返回后AWS转录作业未完成,java,aws-lambda,aws-transcribe,Java,Aws Lambda,Aws Transcribe,我正在尝试在lambda中启动异步转录作业。我配置了一个cloudwatch事件,该事件应在转录作业完成时触发;这样我就可以在不同的lambda中对作业完成执行一些操作。 但问题是,异步转录作业已成功启动,日志中有以下jobResult,但该作业从未完成,且未触发job completed事件 jobResult = java.util.concurrent.CompletableFuture@481a996b[Not completed, 1 dependents] 我的代码在下面几行- p

我正在尝试在lambda中启动异步转录作业。我配置了一个cloudwatch事件,该事件应在转录作业完成时触发;这样我就可以在不同的lambda中对作业完成执行一些操作。 但问题是,异步转录作业已成功启动,日志中有以下jobResult,但该作业从未完成,且未触发job completed事件

jobResult = java.util.concurrent.CompletableFuture@481a996b[Not completed, 1 dependents]
我的代码在下面几行-

public class APIGatewayTranscriptHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        S3Client s3Client = S3Client.create();
        String fileUrl = s3Client.utilities().getUrl(GetUrlRequest.builder().bucket("srcBucket").key("fileName").build()).toString();
        Media media = Media.builder().mediaFileUri(fileUrl).build();

        StartTranscriptionJobRequest request = StartTranscriptionJobRequest.builder().
                languageCode(LanguageCode.ES_ES)
                .media(media).outputBucketName("destBucket")
                .transcriptionJobName("jobName")
                .mediaFormat("mp3")
                .settings(Settings.builder().showSpeakerLabels(true).maxSpeakerLabels(2).build())
                .build();

        TranscribeAsyncClient transcribeAsyncClient = TranscribeAsyncClient.create();
        CompletableFuture<StartTranscriptionJobResponse> jobResult = transcribeAsyncClient.startTranscriptionJob(request);
        logger.log("jobResult =  " + jobResult.toString());
        
        jobResult.whenComplete((jobResponse, err) -> {
            try {
                if (jobResponse != null) {
                    logger.log("CompletableFuture : response = " + jobResponse.toString());
                } else {
                    logger.log("CompletableFuture : NULL response: error = " + err.getMessage());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        //Job is completed only if Thread is made to sleep
        /*try {
                Thread.sleep(50000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/

        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        response.setStatusCode(200);
        Map<String, String> responseBody = new HashMap<String, String>();
        responseBody.put("Status", jobResult.toString());
        String responseBodyString = new JSONObject(responseBody).toJSONString();
        response.setBody(responseBodyString);
        return response;
    }
}
如果增加睡眠时间,每件事都能如期进行。 但是没有Thread.sleep()这个任务永远不会完成。 lambda的超时配置为60秒。
我们将非常感谢您的帮助或指点。

您正在开始一个可完成的未来,但不是等待它完成

调用
get()
等待它等待直到它完成执行

        [...]
        logger.log("jobResult =  " + jobResult.toString());
        jobResult.get();

        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        [...]
这也解释了为什么在调用
sleep()
时它会起作用,因为它为将来的完成提供了足够的时间


即使呼叫仅执行HTTPS请求,lambda也会更快完成(创建HTTPS连接的成本很高)。

您正在启动一个
可完成的未来,但不会等待它完成

调用
get()
等待它等待直到它完成执行

        [...]
        logger.log("jobResult =  " + jobResult.toString());
        jobResult.get();

        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        [...]
这也解释了为什么在调用
sleep()
时它会起作用,因为它为将来的完成提供了足够的时间


即使调用只执行HTTPS请求,lambda也会更快完成(创建HTTPS连接的成本很高)。

实际上,我正在使用jobResult.whenComplete((jobResponse,err))在代码中等待作业完成。我已经用附加代码更新了我的问题。但是我正在启动一个异步作业,不需要lambda等待作业完成。此外,根据输入音频的大小,作业可能需要大量的时间,并且lambda可能会在作业完成之前超时。AWS lambda的最大超时时间为15分钟。它不是等待作业完成。只是等待作业提交
whenComplete
也不会在提交作业之前暂停,而是在作业完成时将操作排队。代码将操作排队以向AWS服务发送消息,但lambda随后到达执行结束时,甚至没有时间实际向服务器发送请求,因为您正在使用异步客户端。按照我的建议,尝试调用
get()
。lambda的执行时间将延长几分之一秒,一切都会很好。我将尝试调用get()并返回结果。实际上,您的建议似乎有效。谢谢。aws文档或示例中没有提到在启动作业后调用get()。我会做更多的测试来确认。再次感谢。这不是AWS的东西,而是Java的一个特性,关于
CompletableFuture
如何工作,以及JVM在HTTPS请求发送之前终止的事实。可能有用的一点是进一步了解这在Java上是如何工作的。安吉丽卡·兰格(Angelika Langer)做了一个非常出色的演示,我推荐的非常多:实际上,我正在等待jobResult.whenComplete((jobResponse,err))代码中的作业完成。我已经用附加代码更新了我的问题。但是我正在启动一个异步作业,不需要lambda等待作业完成。此外,根据输入音频的大小,作业可能需要大量的时间,并且lambda可能会在作业完成之前超时。AWS lambda的最大超时时间为15分钟。它不是等待作业完成。只是等待作业提交
whenComplete
也不会在提交作业之前暂停,而是在作业完成时将操作排队。代码将操作排队以向AWS服务发送消息,但lambda随后到达执行结束时,甚至没有时间实际向服务器发送请求,因为您正在使用异步客户端。按照我的建议,尝试调用
get()
。lambda的执行时间将延长几分之一秒,一切都会很好。我将尝试调用get()并返回结果。实际上,您的建议似乎有效。谢谢。aws文档或示例中没有提到在启动作业后调用get()。我会做更多的测试来确认。再次感谢。这不是AWS的东西,而是Java的一个特性,关于
CompletableFuture
如何工作,以及JVM在HTTPS请求发送之前终止的事实。可能有用的一点是进一步了解这在Java上是如何工作的。安吉丽卡·兰格(Angelika Langer)做了一个精彩的演讲,我推荐的太多了: