I had made a daemon that used a very primitive form of ipc
(telnet and send a String that had certain words in a certain order). I snapped out of it and am now using JSON
to pass messages to a Yesod
server. However, there were some things I really liked about my design, and I'm not sure what my choices are now.
Here's what I was doing:
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 ()
each function in buildSeq looked like this
foo :: Stage -> ReaderT Config IO () data Config = MkConfig (Either JobID Product) BaseDir JobMap
JobMap
is a TMVar Map
that tracks information about current jobs.
so now, what I have are Handlers, that all look like this
foo :: Handler RepJson
foo
represents a command for my daemon, each handler may have to process a different JSON object.
What I would like to do is send one JSON
object that represents success, and another JSON object that espresses information about some exception.
I would like foo
s helper function to be able to return an Either
, but I'm not sure how I get that, plus the ability to terminate evaluation of my list of actions, buildSeq
.
Here's the only choice I see
1) make sure exceptionHandler
is in Handler. Put JobMap
in the App
record. Using getYesod
alter the appropriate value in JobMap
indicating details about the exception, which can then be accessed by foo
Is there a better way?
What are my other choices?
Edit: For clarity, I will explain the role ofHandler RepJson
. The server needs some way to accept commands such as build
stop
report
. The client needs some way of knowing the results of these commands. I have chosen JSON as the medium with which the server and client communicate with each other. I'm using the Handler type just to manage the JSON in/out and nothing more.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With