Shogo's Blog

Aug 9, 2023 - 1 minute read - aws aws-lambda perl

AWS::LambdaがResponse Streamingに対応しました

AWS::LambdaResponse Streamingに対応しました。

Response Streaming

2023年4月に発表されたAWS Lambdaの新機能です。

従来のLambda関数は処理がすべて完了したあとでないと結果を返すことができませんでした。 Response Streamingを利用すると、処理の途中であっても段階的に処理結果を返すことができます。

使い方

通常のLambda関数のなかで使う

CODEリファレンスを返すことでResponse Streamingを使うことができます。

sub handle {
    my ($payload, $context) = @_;
    return sub {
        # とりあえずヘッダーだけ返す
        my $responder = shift;
        my $writer = $responder->('application/json');

        # ...なんか長い処理...

        # 最終的な結果を返す
        $writer->write('{"foo": "bar"}');
        $writer->close;
    };
}

もちろん処理の途中で$writer->writeを複数回呼んで、途中結果を返すことも可能です。

Function URLsと一緒に使う

AWS::Lambda::PSGIを使えばFunction URLsを一緒に使うこともできます。 PSGIDelayed Response and Streaming Body方式に対応しています。

sub app {
    return sub {
        # とりあえずヘッダーだけ返す
        my $responder = shift;
        my $writer = $responder->([200, ['Content-Type' => 'application/json']]);

        # ...なんか長い処理...

        # 最終的な結果を返す
        $writer->write('{"foo": "bar"}');
        $writer->close;
    };
}

Function URLsの設定項目に「呼び出しモード(Invoke Mode)」が追加されました。 RESPONSE_STREAMを設定することでResponse Streamingが利用可能になるのですが、 2023-08-09現在、この設定をLambda関数から読み取る方法は提供されていません。 呼び出しモードによってレスポンスの形式がことなるため、環境変数を使ってAWS::Lambda::PSGIに呼び出しモードを伝える必要があります。

以下はSAM(Serverless Application Model)のテンプレート例です。

ExampleApi:
    Type: AWS::Serverless::Function
    Properties:
        FunctionUrlConfig:
            AuthType: NONE
            InvokeMode: RESPONSE_STREAM
        Environment:
            Variables:
                PERL5_LAMBDA_PSGI_INVOKE_MODE: RESPONSE_STREAM
        # (snip)

Response Streamingを使うとレスポンスサイズの制限が緩和されるという利点もあります。 通常6MBの上限がありますが、これが20MBまでになります。

余談: AWS Lambda Web Adapter

実装している途中でUsing response streaming with AWS Lambda Web Adapter to optimize performance という記事を見つけて、なんとも言えない気持ちになりました。 通常のHTTP APIをLambda Runtime APIに変換するアダプターです。 このアダプターも最近になってResponse Streamingに対応したらしいですね。

まあ、いくらアダプターが高性能でも、アダプターを挟むことによるオーバーヘッドは避けられないでしょうから、 Lambda Runtime APIと直接通信するAWS::Lambdaに分があるはず・・・(要出典)。

まとめ

AWS::LambdaResponse Streamingに対応しました。 処理の途中であっても段階的に処理結果を返すことができ、レスポンスサイズの上限も6MBから20MBに緩和されます。

ぜひお試しください。

参考