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オブジェクトを送信することです。
foo
sヘルパー関数がEither
を返すことができるようにしたいのですが、それを取得する方法がわかりません。さらに、アクションのリストの評価を終了する機能もあります。buildSeq
。
これが私が見る唯一の選択肢です
1)exceptionHandler
がハンドラーにあることを確認します。 JobMap
をApp
レコードに入れます。 getYesod
を使用して、JobMap
の適切な値を変更し、例外の詳細を示します。これは、foo
からアクセスできます。
もっと良い方法はありますか?
私の他の選択肢は何ですか?
編集:わかりやすくするために、Handler RepJson
の役割について説明します。サーバーには、build
stop
report
などのコマンドを受け入れる何らかの方法が必要です。クライアントは、これらのコマンドの結果を知るための何らかの方法を必要としています。サーバーとクライアントが相互に通信するための媒体としてJSONを選択しました。 JSONの入出力を管理するためだけにHandlerタイプを使用しており、それ以上は何も使用していません。
哲学的に言えば、Haskell/Yesodの世界では、値を逆方向に返すのではなく、順方向に渡したいと考えています。したがって、ハンドラーに値を返す代わりに、プロセスの次のステップに転送するように呼び出します。これは、例外を生成する場合があります。
将来のアクションを1つのオブジェクトにバンドルできるので、ハンドラーとfooに継続オブジェクトを渡して、基本的に「完了したら、このコードのブロブを実行する」ように指示できることを忘れないでください。そうすれば、それらは無効になり、何も返さない可能性があります。