AWS Ruby SDK を使用して単純なワークフローとして管理し始めたばかりです。私がすぐに気付いた動作の 1 つは、新しいワークフロー実行を送信する前に、少なくとも 1 つの関連ワーカーと 1 つの関連ディサイダーが実行されている必要があることです。
ワーカーとディサイダーを開始する前に新しいワークフロー実行を送信すると、タイムアウト制限内にある場合でも、タスクが取得されません。どうしてこれなの?HTTP ロング ポーリングがどのように機能するかの説明に基づいて、poll() の呼び出しに到達すると、いずれかのアプリが関連するタスクを受け取ることが期待されます。
ジョブが失敗した後、他のデッドロック状況に遭遇しました (例: ワーカーまたはディサイダーのバグによる、または終了による)。場合によっては、まったく新しいワークフローの実行を再実行したり、開始したりすると、ワークフローの実行がデッドロックすることがあります。最初の決定タスクは、AWS コンソールのワークフロー実行履歴に表示されますが、ディサイダーはそれらを受け取りません。確かに、この問題を確認/テスト ケースに還元するのに苦労していますが、上記の問題に関連していると思われます。これは、およそ 10 ~ 20% の確率で発生します。残りの時間は、すべてが機能します。
他に言及すべき点: 順番に実行される 2 つの別々のアクティビティ タスクに対して、1 つのタスク リストを使用しています。ワーカーとディサイダーの両方が同じタスク リストをポーリングしています。
これが私の労働者です:
require 'yaml'
require 'aws'
config_file_path = File.join(File.dirname(File.expand_path(__FILE__)), 'config.yaml')
config = YAML::load_file(config_file_path)
swf = AWS::SimpleWorkflow.new(config)
domain = swf.domains['test-domain']
puts("waiting for an activity")
domain.activity_tasks.poll('hello-tasklist') do |activity_task|
puts activity_task.activity_type.name
activity_task.complete! :result => name
puts("waiting for an activity")
end
編集
AWS フォーラムの別のユーザーは次のようにコメントしています。
原因は、長いポーリング接続のシャットダウンをすぐに認識しない SWF にあると思います。ワーカーを強制終了すると、しばらくの間その接続はサービスによって開かれていると見なされます。そのため、タスクをディスパッチできます。あなたには、新しい労働者がそれを取得していないように見えます。それを確認する方法は、ワークフローの履歴を確認することです。死んだワーカーのホストと pid を含む識別フィールドを持つアクティビティ タスク開始イベントが表示されます。最終的に、そのようなタスクはタイムアウトになり、ディサイダーによって再試行される可能性があります。
このような状態は、接続を頻繁に終了する単体テスト中に一般的であり、実稼働アプリケーションにとって実際には問題ではないことに注意してください。一般的な回避策は、単体テストごとに異なるタスク リストを使用することです。
これはかなり合理的な説明のようです。これを確認してみます。