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 JSON
do przekazywania wiadomości na Yesod
serwer. 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
JobMap
to narzędzie, TMVar Map
któ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 JSON
obiekt, który reprezentuje sukces, i inny obiekt JSON, który zawiera informacje o jakimś wyjątku.
Chciałbym, aby foo
funkcja 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 exceptionHandler
jest w Handler. Umieść JobMap
w App
protokole. Użycie getYesod
zmienia odpowiednią wartość przy JobMap
wskazywaniu 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.