Skip to content
Snippets Groups Projects
Commit eb0294f5 authored by Jens Nolte's avatar Jens Nolte
Browse files

Refactor ControlSocket stream handling

parent e52b8935
No related branches found
No related tags found
No related merge requests found
...@@ -31,7 +31,8 @@ import System.Environment (getEnv) ...@@ -31,7 +31,8 @@ import System.Environment (getEnv)
type CommandHandler = Command -> IO CommandResult type CommandHandler = Command -> IO CommandResult
data RequestType = Command data Request = Command Command | ConnectBarHost
deriving Show
data Command = SetTheme TL.Text data Command = SetTheme TL.Text
deriving Show deriving Show
...@@ -39,6 +40,7 @@ data Command = SetTheme TL.Text ...@@ -39,6 +40,7 @@ data Command = SetTheme TL.Text
data CommandResult = Success | Error Text data CommandResult = Success | Error Text
deriving Show deriving Show
$(deriveJSON defaultOptions ''Request)
$(deriveJSON defaultOptions ''Command) $(deriveJSON defaultOptions ''Command)
$(deriveJSON defaultOptions ''CommandResult) $(deriveJSON defaultOptions ''CommandResult)
...@@ -68,7 +70,8 @@ ipcSocketAddress MainOptions{socketLocation} = maybe defaultSocketPath (return . ...@@ -68,7 +70,8 @@ ipcSocketAddress MainOptions{socketLocation} = maybe defaultSocketPath (return .
handleEnvError = handle (const $ return Nothing :: IOError -> IO (Maybe FilePath)) . fmap Just handleEnvError = handle (const $ return Nothing :: IOError -> IO (Maybe FilePath)) . fmap Just
sendIpc :: MainOptions -> Command -> IO () sendIpc :: MainOptions -> Command -> IO ()
sendIpc options@MainOptions{verbose} request = do sendIpc options@MainOptions{verbose} command = do
let request = Command command
socketPath <- ipcSocketAddress options socketPath <- ipcSocketAddress options
sock <- socket AF_UNIX Stream defaultProtocol sock <- socket AF_UNIX Stream defaultProtocol
connect sock $ SockAddrUnix socketPath connect sock $ SockAddrUnix socketPath
...@@ -105,22 +108,36 @@ listenUnixSocket options commandHandler = do ...@@ -105,22 +108,36 @@ listenUnixSocket options commandHandler = do
socketHandler :: Socket -> IO () socketHandler :: Socket -> IO ()
socketHandler sock = streamHandler (fromSocket sock 4096) (toSocket sock) socketHandler sock = streamHandler (fromSocket sock 4096) (toSocket sock)
streamHandler :: Producer ByteString IO () -> Consumer ByteString IO () -> IO () streamHandler :: Producer ByteString IO () -> Consumer ByteString IO () -> IO ()
streamHandler producer consumer = do streamHandler producer responseConsumer = do
(decodeResult, leftovers) <- runStateT decode producer (maybeDecodeResult, leftovers) <- runStateT decode producer
response <- maybe (errorResponse "Empty stream") (either handleError (handleCommand leftovers)) decodeResult -- Handle empty result
runEffect (encode response >-> consumer) case maybeDecodeResult of
handleCommand :: Producer ByteString IO () -> Command -> IO CommandResult Nothing -> reply $ errorResponse "Empty stream"
--handleCommand _ Block = error "TODO" -- addBlock $ handleBlockStream leftovers Just decodeResult -> case decodeResult of
handleCommand _ command = commandHandler command Left err -> reply $ handleError err
handleError :: DecodingError -> IO CommandResult Right request -> handleRequest leftovers responseConsumer request
handleError = return . Error . pack . show where
errorResponse :: Text -> IO CommandResult reply :: Producer ByteString IO () -> IO ()
errorResponse message = return $ Error message reply response = runEffect (response >-> responseConsumer)
handleRequest :: Producer ByteString IO () -> Consumer ByteString IO () -> Request -> IO ()
handleRequest _leftovers responseConsumer (Command command) = runEffect (handleCommand command >-> responseConsumer)
--handleRequest leftovers Block = addBlock $ handleBlockStream leftovers
handleRequest _leftovers _responseConsumer ConnectBarHost = error "TODO"
handleCommand :: Command -> Producer ByteString IO ()
handleCommand command = do
result <- liftIO $ commandHandler command
encode result
handleError :: DecodingError -> Producer ByteString IO ()
handleError = encode . Error . pack . show
errorResponse :: Text -> Producer ByteString IO ()
errorResponse message = encode $ Error message
handleBlockStream :: Producer ByteString IO () -> PushBlock handleBlockStream :: Producer ByteString IO () -> PushBlock
handleBlockStream producer = do handleBlockStream producer = do
(decodeResult, leftovers) <- liftIO $ runStateT decode producer (decodeResult, leftovers) <- liftIO $ runStateT decode producer
maybe exitBlock (either (\_ -> exitBlock) (handleParsedBlock leftovers)) decodeResult maybe exitBlock (either (const exitBlock) (handleParsedBlock leftovers)) decodeResult
where where
handleParsedBlock :: Producer ByteString IO () -> String -> PushBlock handleParsedBlock :: Producer ByteString IO () -> String -> PushBlock
handleParsedBlock leftovers update = do handleParsedBlock leftovers update = do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment