93

私は非常に原始的な形式の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 オブジェクトを処理する必要がある場合があります。

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

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

ここに私が見る唯一の選択肢があります

1) exceptionHandlerHandler にあることを確認します。JobMap記録に入れAppます。例外に関する詳細getYesodを示すために適切な値を変更します。JobMapfoo

より良い方法はありますか?

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

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

4

1 に答える 1

9

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

任意の数の将来のアクションを 1 つのオブジェクトにまとめることができるので、継続オブジェクトをハンドラーと foo に渡すことができます。これは基本的に、「完了したら、このコードの塊を実行します」と伝えます。そうすれば、それらは無効になり、何も返されません。

于 2012-10-11T21:37:53.260 に答える