SOを使用してラムダ関数を呼び出し、バックエンドをテストしています。それらを非同期に呼び出したいです。 「invoke_async」は非推奨であり、使用しないでください。代わりに、InvocationTypeを「Event」に設定した「invoke」を使用して、関数を非同期に実行する必要があります。
しかし、関数が戻ったときに関数から応答を取得する方法を理解できないようです。私は次を試しました:
payload3=b"""{
"latitude": 39.5732160891,
"longitude": -119.672918997,
"radius": 100
}"""
client = boto3.client('lambda')
for x in range (0, 5):
response = client.invoke(
FunctionName="loadSpotsAroundPoint",
InvocationType='Event',
Payload=payload3
)
time.sleep(15)
print(json.loads(response['Payload'].read()))
print("\n")
コードを15秒間スリープするように指定しても、応答変数は印刷しようとしても空です。呼び出しInvokationTypeを「RequestResponse」に変更すると、すべて正常に動作し、応答変数が出力されますが、これは同期です。簡単なものが足りませんか?非同期呼び出しが返されたときに、結果を出力するなど、いくつかのコードを実行するにはどうすればよいですか?
ありがとう。
非同期に実行されたAWS Lambda関数は、実行結果を返しません。非同期呼び出しリクエストが成功した場合(つまり、アクセス許可などによるエラーがなかった場合)、AWS LambdaはすぐにHTTPステータスコード 202 ACCEPTED を返し、この非同期呼び出し。
AWS Lambda Invoke action のドキュメントから:
応答構文
HTTP/1.1 StatusCode X-Amz-Function-Error: FunctionError X-Amz-Log-Result: LogResult Payload
応答要素
アクションが成功すると、サービスは次のHTTP応答を送り返します。
StatusCode
HTTPステータスコードは、リクエストが成功した場合、200の範囲になります。
RequestResponse
呼び出しタイプの場合、このステータスコードは200です。Event
呼び出しタイプの場合、このステータスコードは202。DryRun
呼び出しタイプの場合、ステータスコードは204になります。[...]
応答は、HTTP本文として次を返します。
ペイロード
Lambda関数によって返されるオブジェクトのJSON表現です。 これは、呼び出しタイプが
RequestResponse
の場合にのみ存在します。
'async AWS lambda invocation'と 'async python code'には違いがあります。 InvocationType
を'Event'
に設定すると、 定義により になり、応答が返されなくなります。
あなたの例では、invoke()
はすぐにNone
を返し、後で値を変更するために暗黙的にバックグラウンドで何かを起動しません(ありがとうございます!)。したがって、15秒後にresponse
の値を見ると、_None
のままです。
非同期のPythonコードを持つRequestResponse
呼び出しタイプが本当に必要なようです。選択肢はたくさんありますが、私のお気に入りは concurrent.futures
です。もう1つは threading
です。
concurrent.futures
を使用した例を次に示します。
(Python2を使用している場合、pip install futures
が必要です)
from concurrent.futures import ThreadPoolExecutor
import json
payload = {...}
with ThreadPoolExecutor(max_workers=5) as executor:
futs = []
for x in xrange(0, 5):
futs.append(
executor.submit(client.invoke,
FunctionName = "loadSpotsAroundPoint",
InvocationType = "RequestResponse",
Payload = bytes(json.dumps(payload))
)
)
results = [ fut.result() for fut in futs ]
print results
検討したいもう1つのパターンは、Event
呼び出しタイプを使用し、Lambda関数がメッセージをSNSにプッシュし、それが別のLambda関数によって消費されるようにすることです。 SNSトリガーラムダ関数 here のチュートリアルをご覧ください。