Excepciones en Yesod

93

Había creado un demonio que usaba una forma muy primitiva de ipc(telnet y enviar una cadena que tenía ciertas palabras en un orden determinado). Salí de él y ahora lo estoy usando JSONpara pasar mensajes a un Yesodservidor. Sin embargo, hubo algunas cosas que realmente me gustaron de mi diseño y no estoy seguro de cuáles son mis opciones ahora.

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 se veía así

foo :: Stage -> ReaderT Config IO ()

data Config = MkConfig (Either JobID Product) BaseDir JobMap

JobMapes un TMVar Mapque rastrea información sobre trabajos actuales.

así que ahora, lo que tengo son controladores, que todos se ven así

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 JSONobjeto que represente el éxito y otro objeto JSON que exprese información sobre alguna excepción.

Me gustaría foos función auxiliar para poder devolver una 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.

Esta es la única opción que veo

1) asegúrese de que exceptionHandleresté en Handler. Ponga JobMapel Appregistro. El uso de getYesodalterar el valor apropiado para JobMapindicar detalles sobre la excepción, a la que luego se puede acceder mediantefoo

¿Existe una forma mejor?

¿Cuáles son mis otras opciones?

Editar: Para mayor claridad, explicaré el papel de Handler RepJson. El servidor necesita alguna forma de aceptar comandos como build stop report. 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 Handler solo para administrar JSON in / out y nada más.

Michael Litchard
fuente

Respuestas:

9

Hablando filosóficamente, en el mundo Haskell / Yesod, desea transmitir los valores hacia adelante, en lugar de devolverlos al revés. Entonces, en lugar de que los controladores devuelvan un valor, pídales que llamen hacia el 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 controladores y foos que básicamente les dice: "Una vez que haya terminado, ejecute este blob de código". De esa forma pueden anularse y no devolver nada.

Tyler Durden
fuente