YesodのgetAuthEntityは内部でrunDBを使っているのでデッドロックに注意しましょう
getAuthEntity
Yesodの
getAuthEntity
はデフォルトでrunDB
を使っています.
これがどういうことなのかと言うと,
これに依存しているmaybeAuth
などを使うとYesodDB
などを見ることなくデータベースコネクションを取ってきてしまうため,
runDB
の内部で使ったりするとデッドロックを引き起こす危険性があります.
ユーザ情報を取ってくるので当然と言えば当然なのですが, Cookieに入っているものと混同しやすくもあります.
権限確認などを行う場合注意しましょう.
検出方法
プロファイルビルドを有効にしてrunDB
のaction
に
whoCreated
をかけて出力を見ると何処からrunDB
が実行されているのか確認できます.
安全確認方法
YESOD_PGPOOLSIZE
を1
にして各ページでテストを行えばデータベースコネクションを同時に1つしか使っていないことを確認できます.
理想
runDB
したアクションをYesodDB
内部に持てないようにして欲しいですね.
多分Handler
が万能すぎるのが悪いのかと思います.
runDB
したらDBRunned
みたいな型にコンテキストを包んでHandler
やYesodDB
に戻すのはunsafeとか命名して慎重な動作を必要とするのが良いと思います.
Handler
をYesodDB
に変換しにくくするのはしんどすぎるのでやめた方が良さそうですね.
そうすると現在のHaskellの型システムでもデッドロックを分かり易くできます. 現実のフレームワークにこの考えを落とし込んでプログラムしやすくなるかは実証していませんが.