最近、AWS Step Functions を使ってみたのですが、これが中々面白い。ステートマシンというワークフローを定義して、予め作っておいた Lambda 関数群を順に実行して出力値を次の関数に渡したり、分岐・ループ、並列実行等もできちゃう。Lambda 関数を Unix コマンドになぞらえると Step Functions はシェルスクリプトですな。単純な機能の Lambda 関数を組み合わせて複雑な処理が可能になるので、バッチ処理的なユースケースでサーバレス化が捗りそうです。
そんな便利な Step Functions ですが、ステートマシンの作り方等は他に解説がいくらでもあるので、今回は作ったステートマシンを PHP プロうグラムから実行する話。単純な要件だけど、コードサンプルが意外に見つからなかったもので。
以下、ステートマシンを非同期に実行開始して、1秒毎に状態取得・出力するという例です。AWS SDK for PHP 3 が必要なので、下記スクリプトのある場所で composer require aws/aws-sdk-php してある前提です。
<?php require_once('./vendor/autoload.php'); define('AWS_ACCESS_KEY', <あなたのアクセスキー>); define('AWS_SECRET_ACCESS_KEY', <あなたのシークレットアクセスキー>); define('AWS_REGION', <リージョン>); define('STATEMACHINE_ARN', <あなたのステートマシンのARN>); // Step Functions クライアント生成 $credentials = new Aws\Credentials\Credentials(AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY); $sfn = new Aws\Sfn\SfnClient([ 'region' => AWS_REGION, 'version' => 'latest', 'credentials' => $credentials ]); // ステートマシンの実行を開始 $input = [ "var1" => "a", "var2" => "b", "var3" => "c", ]; $result = $sfn->startExecution([ 'stateMachineArn' => STATEMACHINE_ARN, 'input' => json_encode($input) ]); $executionArn = $result['executionArn']; // 実行状態を監視しつつ終了まで待つ for ($events=[],$expire=time() + 60; time() < $expire;) { sleep(1); // 実行状態を取得 $result = $sfn->describeExecution([ 'executionArn' => $executionArn ]); $status = $result['status']; // イベント履歴を取得 $result = $sfn->getExecutionHistory([ 'executionArn' => $executionArn ]); // 発生したイベントを表示 $newEvents = array_slice($result['events'], count($events)); foreach ($newEvents as $newEvent) { printf("[%d] %s\n", $newEvent['id'], $newEvent['type']); } $events = $result['events']; if ($status != 'RUNNING') { break; } }
Lambda 関数の内部でもプログレスを DynamoDB 等に出力するようにすれば、より詳しい監視が可能になるかも。逆にそこまで詳しく状態把握する必要がなければ、startExecution() を startSyncExecution() にすると簡単に同期処理できます。