Yesod 的例外情况

我创建了一个守护进程,它使用了非常原始的 ipc形式(telnet 并发送一个具有特定顺序的特定单词的 String)。我迅速从中恢复过来,现在正在使用 JSONYesod服务器传递消息。然而,有一些东西我真的很喜欢我的设计,我不知道我现在的选择是什么。

我是这么做的:

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对象和另一个表示某些异常信息的 JSON 对象。

我希望 foos 的 helper 函数能够返回一个 Either,但是我不确定我是如何得到它的,另外还有终止对我的操作列表 buildSeq求值的能力。

这是我唯一的选择

1)确保 exceptionHandler在 Handler 中。将 JobMap放入 App记录中。使用 getYesod修改 JobMap中指示异常详细信息的适当值, 然后可以通过 foo访问

还有更好的办法吗?

我还有别的选择吗?

编辑: 为了清楚起见,我将解释 Handler RepJson的作用。服务器需要一些方法来接受诸如 build stop report之类的命令。客户端需要某种方法来了解这些命令的结果。我选择了 JSON 作为服务器和客户机相互通信的媒介。我使用 Handler 类型仅仅是为了管理 JSON 的输入/输出,仅此而已。

3358 次浏览

Philosophically speaking, in the Haskell/Yesod world you want to pass the values forward, rather than return them backwards. So instead of having the handlers return a value, have them call forwards to the next step in the process, which may be to generate an exception.

Remember that you can bundle any amount of future actions into a single object, so you can pass a continuation object to your handlers and foos that basically tells them, "After you are done, run this blob of code." That way they can be void and return nothing.