web-dev-qa-db-ja.com

Yesodの例外

ipcの非常に原始的な形式を使用するデーモンを作成しました(telnetを使用して、特定の単語を特定の順序で含む文字列を送信します)。私はそれからスナップアウトし、現在JSONを使用してメッセージをYesodサーバーに渡します。しかし、自分のデザインが本当に気に入った点がいくつかあり、今の自分の選択がよくわかりません。

これが私がしていたことです:

buildManager :: Phase -> IO ()
buildManager phase = do
  let buildSeq = findSeq phase
      jid = JobID $ pack "8"
      config = MkConfig $ Just jid
  flip C.catch exceptionHandler $ 
  runReaderT (sequence_ $ buildSeq <*> stages) config
  -- ^^ I would really like to keep the above line of code, or something like it.
  return ()

buildSeqの各関数は次のようになりました

foo :: Stage -> ReaderT Config IO ()

data Config = MkConfig (Either JobID Product) BaseDir JobMap

JobMapは、現在のジョブに関する情報を追跡するTMVar Mapです。

だから今、私が持っているのはハンドラーです、それはすべてこのように見えます

foo :: Handler RepJson

fooは私のデーモンのコマンドを表し、各ハンドラーは異なるJSONオブジェクトを処理する必要がある場合があります。

私がやりたいのは、成功を表す1つのJSONオブジェクトと、いくつかの例外に関する情報を抑制する別のJSONオブジェクトを送信することです。

foosヘルパー関数がEitherを返すことができるようにしたいのですが、それを取得する方法がわかりません。さらに、アクションのリストの評価を終了する機能もあります。buildSeq

これが私が見る唯一の選択肢です

1)exceptionHandlerがハンドラーにあることを確認します。 JobMapAppレコードに入れます。 getYesodを使用して、JobMapの適切な値を変更し、例外の詳細を示します。これは、fooからアクセスできます。

もっと良い方法はありますか?

私の他の選択肢は何ですか?

編集:わかりやすくするために、Handler RepJsonの役割について説明します。サーバーには、buildstopreportなどのコマンドを受け入れる何らかの方法が必要です。クライアントは、これらのコマンドの結果を知るための何らかの方法を必要としています。サーバーとクライアントが相互に通信するための媒体としてJSONを選択しました。 JSONの入出力を管理するためだけにHandlerタイプを使用しており、それ以上は何も使用していません。

94

哲学的に言えば、Haskell/Yesodの世界では、値を逆方向に返すのではなく、順方向に渡したいと考えています。したがって、ハンドラーに値を返す代わりに、プロセスの次のステップに転送するように呼び出します。これは、例外を生成する場合があります。

将来のアクションを1つのオブジェクトにバンドルできるので、ハンドラーとfooに継続オブジェクトを渡して、基本的に「完了したら、このコードのブロブを実行する」ように指示できることを忘れないでください。そうすれば、それらは無効になり、何も返さない可能性があります。

10
Tyler Durden