GAEでHardDeadlineExceededErrorが出た

例外の内容

com.google.apphosting.runtime.HardDeadlineExceededError: This request (43f315102efbed5) started at 2009/06/21 12:32:44.564 UTC and was still executing at 2009/06/21 12:33:13.433 UTC.
	at sun.misc.Unsafe.park(Native Method)
	at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(Unknown Source)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(Unknown Source)
	at java.util.concurrent.CountDownLatch.await(Unknown Source)

原因

GAEには1リクエストで30秒以内に処理しなければいけないという制限がある。その制限を越えてしまった場合にエラーが発生する。

対応

対応としては30秒以内に終わるようにしなければいけないということになるが、実際のところは30秒で処理しきれないものやなんらかの原因で処理時間が多くなってしまうことがある場合も含めて考えるとキューを実装した方がいいということになるだろう。処理キュー用のテーブルを作成しておきCronでキューテーブルを読み込み処理を行う。そして、Cronでは何回実行されても同じ結果になるようにすることが要求される。実際に私がいま作成しているシステムではメール送信を行うことをしている。メール送信では1リクエストで30秒以内の制限以外に下記の制限が存在する。

1分間に32件までしかMailAPIの呼出ができないためMailQueueというテーブルを作成すると共にメール送信用のCronをしかけている。そして、Cronの中ではMailQueueを32件検索しメール送信するという単純な仕組みだ。これで各画面ではこの制限を考慮せずに設計することができる。(各画面はMailQueueにinsertするだけ)こういった仕組みを考える必要があるのがGAEと付き合っていくには不可欠ではないかと思っている。とはいえ、まだ試行錯誤中だが。