英文:
AWS transcription job does not complete after lambda returns
问题
我正在尝试在 Lambda 内部启动一个异步转录作业。我已经配置了一个 CloudWatch 事件,该事件应在转录作业完成时触发,以便我可以在另一个 Lambda 中在作业完成时执行一些操作。但问题是,异步转录作业成功启动,并在日志中显示以下 jobResult,但作业永远不会完成,也不会触发作业完成事件。
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;
}
}
我已经验证,音频文件存在于源存储桶中。
只有在启动作业后在 Lambda 中添加一些休眠时间后,作业才会完成并触发作业完成事件。
例如,
Thread.sleep(50000);
只有添加 Thread.sleep() 后,一切都按预期工作。但是如果没有 Thread.sleep(),作业永远不会完成。Lambda 的超时时间配置为 60 秒。非常感谢提供帮助或指导。
英文:
I am trying to launch an async transcription job inside a lambda. I have a cloudwatch event configured that should trigger on completion of the transcription job; So that I can perform some action on job completion in a different lambda.
But the problem is that the async transcription job is lauched successfully with following jobResult in the log but the job never completes and the job completed event is not triggered.
jobResult = java.util.concurrent.CompletableFuture@481a996b[Not completed, 1 dependents]
My code is on following lines -
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;
}
}
I have verified, the audio file exists in the source bucket.
The above job completes and the job completed event is triggered ONLY if I add some sleep time in the lambda after launching the job.
For example,
Thread.sleep(50000);
Every thing works as expected if sleep time is added.
But without Thread.sleep() the job never completes.
The Timeout for lambda is configured as 60 seconds.
Some help or pointers will be really appreciated.
答案1
得分: 2
你正在启动一个 CompletableFuture
,但没有等待它完成。
调用 get()
来等待它完成执行。
[...]
logger.log("jobResult = " + jobResult.toString());
jobResult.get();
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
[...]
这也解释了为什么在调用 sleep()
时它可以工作,因为这给了未来完成的足够时间。
即使这个调用只是进行了一个 HTTPS 请求,Lambda 也会更早地完成(创建 HTTPS 连接是昂贵的)。
英文:
You are starting a CompletableFuture
, but not waiting for it to complete.
Call get()
to wait for it to wait util it completes executing.
[...]
logger.log("jobResult = " + jobResult.toString());
jobResult.get();
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
[...]
This also explains why it works when you do call sleep()
, as it gives enough time to the Future to complete.
Even if the call only does an HTTPS request, the lambda will finish sooner (HTTPS connections are expensive to create).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论