Wyjątki w Yesod

93

Zrobiłem demona, który używał bardzo prymitywnej formy ipc(telnet i wysyłanie łańcucha, który zawierał określone słowa w określonej kolejności). Wyskoczyłem z tego i używam teraz JSONdo przekazywania wiadomości na Yesodserwer. Jednak było kilka rzeczy, które bardzo mi się podobały w moim projekcie i nie jestem pewien, jakie mam teraz wybory.

Oto, co robiłem:

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

każda funkcja w buildSeq wyglądała tak

foo :: Stage -> ReaderT Config IO ()

data Config = MkConfig (Either JobID Product) BaseDir JobMap

JobMapto narzędzie, TMVar Mapktóre śledzi informacje o aktualnych ofertach pracy.

więc teraz mam Handlery, które wyglądają tak

foo :: Handler RepJson

foo reprezentuje polecenie dla mojego demona, każdy program obsługi może musieć przetwarzać inny obiekt JSON.

To, co chciałbym zrobić, to wysłać jeden JSONobiekt, który reprezentuje sukces, i inny obiekt JSON, który zawiera informacje o jakimś wyjątku.

Chciałbym, aby foofunkcja pomocnicza mogła zwracać Either, ale nie jestem pewien, jak to osiągnę, plus możliwość zakończenia oceny mojej listy działań,buildSeq .

Oto jedyny wybór, jaki widzę

1) upewnij się, że exceptionHandlerjest w Handler. Umieść JobMapw Appprotokole. Użycie getYesodzmienia odpowiednią wartość przy JobMapwskazywaniu szczegółów dotyczących wyjątku, do których można następnie uzyskać dostępfoo

Czy jest lepszy sposób?

Jakie mam inne możliwości?

Edycja: Dla jasności wyjaśnię rolę Handler RepJson. Serwer potrzebuje sposobu na akceptowanie poleceń, takich jak build stop report. Klient potrzebuje jakiegoś sposobu poznania wyników tych poleceń. Jako medium, z którym komunikują się serwer i klient, wybrałem JSON. Używam typu Handler tylko do zarządzania wejściem / wyjściem JSON i nic więcej.

Michael Litchard
źródło

Odpowiedzi:

9

Mówiąc filozoficznie, w świecie Haskell / Yesod chcesz przekazać wartości do przodu, zamiast zwracać je wstecz. Dlatego zamiast sprawić, by programy obsługi zwracały wartość, poproś ich o wywołanie następnego kroku w procesie, którym może być wygenerowanie wyjątku.

Pamiętaj, że możesz spakować dowolną liczbę przyszłych działań w jeden obiekt, dzięki czemu możesz przekazać obiekt kontynuacji do swoich programów obsługi i foos, który w zasadzie mówi im: „Po zakończeniu uruchom ten fragment kodu”. W ten sposób mogą być puste i nic nie zwracać.

Tyler Durden
źródło