googleapis/google-cloud-go を使用して Cloud Tasks API の CreateTask()
実行したところ 30 秒より大きいタイムアウトは設定できないというエラーメッセージ (The deadline cannot be more than 30s in the future.
) が返ってきたので調べてみました。
同じ問題に遭遇した例がないか探す
エラーメッセージで調べたところ次の Issue が見つかりました。
(クローズされていますが内容を見る限りでは未解決のままです)
個々のリクエストでタイムアウトを指定したつもりはなかったのですが context に設定したタイムアウトが 30 秒より大きいと Cloud Tasks API のサーバーがエラーを返すようです。
タイムアウトはどのようにしてサーバーに伝わるのか?
googleapis/google-cloud-go
が使用している grpc/grpc-go 内で context に設定された deadline を grpc-timeout
ヘッダに設定しています。
実は gRPC においてタイムアウトはクライアントのみが参照する情報ではありません。
gRPC のドキュメントにもサーバーは RPC がタイムアウトしていないか、または残り時間を取得できるとあります。
gRPC の Blog でも無制限のリソース消費を避けるためにはサービス (今回は Cloud Tasks API) で適切な最長タイムアウトを指定する必要があるとしています。
つまり context に設定したタイムアウトがサーバーに伝わることも、サーバーがそのタイムアウトをチェックすることも正しい動作になります。
ドキュメントの記載を確認する
googleapis/google-cloud-go
のドキュメントにはタイムアウトを設定していない context で非ストリーミング系 API が呼ばれた場合はデフォルトタイムアウトを設定する旨が記載されています。
例えば CreateTask()
の場合は 10 秒のタイムアウトを設定しています。
しかし、 Cloud Tasks API がサポートするタイムアウト上限について記載されたドキュメントは見つけられませんでした。
まとめ
- gRPC クライアントが設定したタイムアウトは gRPC サーバーでも参照できる
- 設定によってはパラメータ不正でエラーになる
- Cloud Tasks API は context に 30 秒より大きいタイムアウトを設定するとエラーを返す
- 30 秒という閾値はドキュメント化されていない