2016-11-28 56 views
5

我想从另一个Java Lambda函数内异步调用Java Lambda函数。我只是想开火并忘记,但使用.invokeAsync(InvokeRequest),我必须在Future上调用.get(),然后阻止并打破“火再遗忘”用例。替代AWS Lambda invokeAsync(不建议使用)

这里是我尝试使用代码:

private void sendToDownloader(String payload) throws InterruptedException, ExecutionException { 
    log.info(payload); 
    InvokeRequest invoke = new InvokeRequest(); 
    invoke.withFunctionName("LambdaTwo") 
      .withPayload(payload) 
      .withInvocationType(InvocationType.Event); 

    lambdaClient.invokeAsync(invoke).get(); 
} 

如果我删除获得()方法调用,它实际上并没有调用LambdaTwo。

应该指出,这个lambda函数在调用LambdaTwo后立即结束。

同时,我尝试使用下面的代码:

private void sendToDownloader(String payload) throws InterruptedException, ExecutionException { 
    log.info(payload); 
    InvokeAsyncRequest invoke = new InvokeAsyncRequest(); 
    invoke.withFunctionName("LambdaTwo") 
      .withInvokeArgs(payload); 

    lambdaClient.invokeAsync(invoke); 
} 

此代码的工作,但.invokeAsync已被废弃,它说,看到“调用API”,为此,我无法找到任何文件。

任何人都可以让我以正确的方式调用Lambda函数吗?

编辑1 佩尔马克的建议,我已经重写了下面的代码,但它似乎阻止而LambdaTwo函数执行。

public void routeEvent(String lambdaName, String cacheName) throws InterruptedException, ExecutionException, JsonProcessingException { 
    ObjectNode obj = new ObjectNode(JsonNodeFactory.instance); 
    obj.put("nodeName", cacheName); 
    InvokeRequest invoke = new InvokeRequest(); 
    invoke.withFunctionName(lambdaName) 
      .withInvocationType(InvocationType.Event) 
      .withPayload(OBJECT_MAPPER.writeValueAsString(obj)); 

    log.info(System.currentTimeMillis()); 
    lambdaClient.invoke(invoke); 
    log.info(System.currentTimeMillis()); 
} 

它打印出以下毫秒。

2016年11月28日3时41分35秒INFO LambdaFunction:97 - 1480304495867
2016年11月28日3点41分41秒INFO LambdaFunction:99 - 1480304501432

是有区别的两者之间约5.5秒,而Lambda持续时间证实了这一点。

EDIT 2 只是为了澄清,我正在尝试AWSLambdaAsyncClient调用.invokeAsync(InvokeRequest)和.invoke(InvokeRequest)和既不工作。当调用invokeAsync时,它实际上并不调用Lambda函数,除非我调用它上面的.get(),然后在第二个Lambda函数执行时阻塞。

最后的工作是调用.invokeAsync(InvokeRequest),但不调用InvokeRequest对象上的.withInvocationType(InvocationType.Event)。目前还不清楚为什么会导致异步行为,但这是工作而不使用废弃的方法。

public void routeEventAsync2(String lambdaName, String cacheName) throws InterruptedException, ExecutionException, JsonProcessingException { 
    ObjectNode obj = new ObjectNode(JsonNodeFactory.instance); 
    obj.put("nodeName", cacheName); 
    InvokeRequest invoke = new InvokeRequest(); 
    invoke.withFunctionName(lambdaName) 
      .withPayload(OBJECT_MAPPER.writeValueAsString(obj)); 

    lambdaAsyncClient.invokeAsync(invoke); 
} 

回答

3

有关此方法弃用的文档很混乱。他们试图说的是使用AWSLambdaClient.invoke(request)。您需要将请求对象上的InvocationType设置为Event,以便在不等待响应的情况下调用Lambda函数。

+0

因此,整个AWSLambdaAsyncClient已被弃用? AWSLambdaClient的Javadoc说所有的服务调用都会阻塞... – Brooks

+0

你没有提到你在你的问题中使用了'AWSLambdaAsyncClient'。看一下这个类的javadoc,它只说'invokeAsyncAsync()'已被弃用。你使用的'invokeAsync()'方法应该没问题。 HTTP://docs.aws.amazon。com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/lambda/AWSLambdaAsyncClient.html –

+0

对不起,我应该提到这一点。我通过你的回答得到了正确答案,但由于某种原因,将InvocationType设置为事件导致了同步行为。 – Brooks