module System.Nix.Store.Remote.Logger (
Logger(..)
, Field(..)
, processOutput)
where
import Control.Monad.Reader (ask, liftIO)
import Data.Binary.Get
import Network.Socket.ByteString (recv)
import System.Nix.Store.Remote.Types
import System.Nix.Util
controlParser :: Get Logger
controlParser = do
ctrl <- getInt
case (ctrl :: Int) of
0x6f6c6d67 -> Next <$> getByteStringLen
0x64617461 -> Read <$> getInt
0x64617416 -> Write <$> getByteStringLen
0x616c7473 -> pure Last
0x63787470 -> flip Error <$> getByteStringLen <*> getInt
0x53545254 -> StartActivity <$> getInt <*> getInt <*> getInt <*> getByteStringLen <*> getFields <*> getInt
0x53544f50 -> StopActivity <$> getInt
0x52534c54 -> Result <$> getInt <*> getInt <*> getFields
x -> fail $ "Invalid control message received:" ++ show x
processOutput :: MonadStore [Logger]
processOutput = go decoder
where decoder = runGetIncremental controlParser
go :: Decoder Logger -> MonadStore [Logger]
go (Done _leftover _consumed ctrl) = do
case ctrl of
e@(Error _ _) -> return [e]
Last -> return [Last]
x -> do
next <- go decoder
return $ x:next
go (Partial k) = do
soc <- ask
chunk <- liftIO (Just <$> recv soc 8)
go (k chunk)
go (Fail _leftover _consumed msg) = do
error msg
getFields :: Get [Field]
getFields = do
cnt <- getInt
sequence $ replicate cnt getField
getField :: Get Field
getField = do
typ <- getInt
case (typ :: Int) of
0 -> LogInt <$> getInt
1 -> LogStr <$> getByteStringLen
x -> fail $ "Unknown log type: " ++ show x