Last active
August 5, 2019 22:28
-
-
Save akshaymankar/8294788b6d9a9dd01a59573147f9afa1 to your computer and use it in GitHub Desktop.
TypedWatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
module TypedWatch where | |
import Control.Exception.Safe | |
import Data.Aeson | |
import Data.Function ((&)) | |
import Data.Text (Text) | |
import Kubernetes.Client.Watch | |
import Kubernetes.OpenAPI | |
import Network.HTTP.Client (Manager) | |
import Streaming.Prelude (Of, Stream) | |
import Kubernetes.OpenAPI.API.CoreV1 | |
import qualified Data.ByteString.Streaming.Char8 as Q | |
import qualified Data.Text.IO as T | |
import qualified Streaming.Prelude as S | |
import qualified Data.Map as Map | |
-- | Parse the stream using the given parser. | |
streamParse :: | |
FromJSON a => Q.ByteString IO r -> Stream (Of (Either String a)) IO r | |
streamParse byteStream = do | |
decodeJSON $ Q.lines $ byteStream | |
-- | Parse a single event from the stream. | |
decodeJSON :: | |
(FromJSON a, Monad m) => | |
Stream (Q.ByteString m) m r -> Stream (Of (Either String a)) m r | |
decodeJSON byteStream = S.map eitherDecode (S.mapped Q.toLazy byteStream) | |
dispatchTypedWatch :: | |
(HasOptionalParam req Watch, MimeType accept, MimeType contentType, | |
FromJSON a) => | |
Manager | |
-> KubernetesClientConfig | |
-> KubernetesRequest req contentType resp accept | |
-> (Stream (Of (Either String (WatchEvent a))) IO () -> IO ()) | |
-> IO () | |
dispatchTypedWatch mgr cfg req f = do | |
let withResponseBody body = streamParse body & f | |
dispatchWatch mgr cfg req (withResponseBody) | |
-- Example usage | |
printPodEvent :: Either String (WatchEvent V1Pod) -> IO () | |
printPodEvent (Right w) = T.putStrLn $ eventType w <> " -> " <> podName (eventObject w) | |
printPodEvent (Left e) = error e | |
podName :: V1Pod -> Text | |
podName pod = case v1PodMetadata pod >>= v1ObjectMetaName of | |
Nothing -> "unnamed-pod" | |
Just n -> n | |
program :: Manager -> KubernetesClientConfig -> IO () | |
program mgr cfg = do | |
let listFn = listNamespacedPod (Accept MimeJSON) (Namespace "default") | |
dispatchTypedWatch mgr cfg listFn (S.mapM_ printPodEvent) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment