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.