2012-04-12 17 views
93

Había creado un daemon que usaba una forma muy primitiva de ipc (telnet y enviaba una cadena que tenía ciertas palabras en cierto orden). Salí de él y ahora estoy usando JSON para pasar mensajes a un servidor Yesod. Sin embargo, hubo algunas cosas que realmente me gustaron de mi diseño, y no estoy seguro de cuáles son mis opciones ahora.Excepciones en Yesod

Esto es lo que estaba haciendo:

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() 

cada función en buildSeq veía así

foo :: Stage -> ReaderT Config IO() 

data Config = MkConfig (Either JobID Product) BaseDir JobMap 

JobMap es un TMVar Map que rastrea información sobre los trabajos actuales.

por lo que ahora, lo que tengo son los manipuladores, que todos se parecen a este

foo :: Handler RepJson 

foo representa un comando para mi demonio, cada controlador puede tener que procesar un objeto JSON diferente.

Lo que me gustaría hacer es enviar un objeto JSON que represente el éxito, y otro objeto JSON que exprese información sobre alguna excepción.

Quisiera foo s función auxiliar para poder devolver un Either, pero no estoy seguro de cómo consigo que, además de la posibilidad de suspender la evaluación de mi lista de acciones, buildSeq.

Aquí es la única opción que veo

1) asegurarse de que está en exceptionHandler Handler. Ponga JobMap en el registro App. Usando getYesod altera el valor apropiado en JobMap indicando los detalles acerca de la excepción, que luego se puede acceder por foo

¿Hay una mejor manera?

¿Cuáles son mis otras opciones?

Editar: Para mayor claridad, explicaré el papel de Handler RepJson. El servidor necesita alguna manera de aceptar comandos como buildstopreport. El cliente necesita alguna forma de conocer los resultados de estos comandos. He elegido JSON como el medio con el que el servidor y el cliente se comunican entre sí. Estoy usando el tipo de controlador solo para administrar la entrada/salida JSON y nada más.

Respuesta

9

Filosóficamente hablando, en el mundo de Haskell/Yesod quieres pasar los valores hacia adelante, en lugar de devolverlos hacia atrás. Entonces, en lugar de hacer que los manejadores devuelvan un valor, pídales que lo desvíen al siguiente paso del proceso, que puede ser generar una excepción.

Recuerde que puede agrupar cualquier cantidad de acciones futuras en un solo objeto, por lo que puede pasar un objeto de continuación a sus manejadores y foos que básicamente les dice: "Después de que termine, ejecute este bloque de código". De esa manera pueden ser nulos y no devolver nada.

+0

Gracias por su comprensión, Tyler Durden. –