Исключения в Йесод

Я создал демона, который использовал очень примитивную форму 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, который представляет успех, и другой объект JSON, который содержит информацию о каком-то исключении.

Я хотел бы, чтобы вспомогательная функция foos могла возвращать Either, но я не знаю, как это сделать, а также возможность прекратить оценку моего списка действий, buildSeq.

Вот единственный выбор, который я вижу

1) убедитесь, что exceptionHandler находится в обработчике. Поместите JobMap в запись App. Используя getYesod, измените соответствующее значение в JobMap, указав подробности об исключении, к которым затем можно получить доступ с помощью foo.

Есть ли способ лучше?

Каковы мои другие варианты?

Редактировать: для ясности я объясню роль Handler RepJson. Серверу нужен способ принимать такие команды, как build stop report. Клиенту нужен какой-то способ узнать результаты этих команд. Я выбрал JSON в качестве среды, с помощью которой сервер и клиент общаются друг с другом. Я использую тип Handler только для управления вводом/выводом JSON и не более того.


person Michael Litchard    schedule 12.04.2012    source источник


Ответы (1)


С философской точки зрения, в мире Haskell/Yesod вы хотите передавать значения вперед, а не возвращать их назад. Таким образом, вместо того, чтобы обработчики возвращали значение, пусть они вызывают переадресацию на следующий шаг в процессе, который может заключаться в создании исключения.

Помните, что вы можете объединить любое количество будущих действий в один объект, поэтому вы можете передать объект продолжения своим обработчикам и foos, который, по сути, говорит им: «После того, как вы закончите, запустите этот блок кода». Таким образом, они могут быть недействительными и ничего не возвращать.

person Tyler Durden    schedule 11.10.2012