2012-04-12 2 views
93

Я создал демона, который использовал очень примитивную форму ipc (telnet и отправить строку, содержащую определенные слова в определенном порядке). Я отключил его, и теперь я использую JSON для передачи сообщений на сервер Yesod. Тем не менее, некоторые вещи мне очень понравились в моем дизайне, и я не уверен, каковы мои варианты сейчас.Исключения в 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, который передает информацию об одном исключении.

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

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

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

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

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

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

ответ

9

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

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

+0

Спасибо за ваше понимание, Тайлер Дерден. –