{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}

{- | Description: A specialized channel for outgoing peer messages. -}
module OM.Legion.MsgChan (
  MsgChan,
  Peer(..),
  ClusterName(..),
  MessageId(..),
  PeerMessage(..),
  close,
  enqueueMsg,
  newMsgChan,
  stream,
) where

import Control.Concurrent.STM (TVar, atomically, newTVarIO, readTVar,
  retry, writeTVar)
import Control.Monad (join)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Binary (Binary, Word64)
import Data.ByteString.Lazy (ByteString)
import Data.CRDT.EventFold (Event(Output, State), Diff, EventFold,
  EventId)
import Data.Foldable (traverse_)
import Data.Map (Map)
import Data.String (IsString)
import Data.Text (Text)
import Data.UUID (UUID)
import GHC.Generics (Generic)
import Web.HttpApiData (FromHttpApiData, ToHttpApiData)
import Streaming.Prelude (Stream, Of)
import qualified Streaming.Prelude as Stream


{- | A specialized channel for outgoing peer messages.  -}
newtype MsgChan e = MsgChan
  { forall e. MsgChan e -> TVar (Maybe [PeerMessage e])
_unMsgChan :: TVar (Maybe [PeerMessage e])
  }


{- | Create a new 'MsgChan'. -}
newMsgChan :: (MonadIO m) => m (MsgChan e)
newMsgChan :: forall (m :: * -> *) e. MonadIO m => m (MsgChan e)
newMsgChan = IO (MsgChan e) -> m (MsgChan e)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MsgChan e) -> m (MsgChan e))
-> IO (MsgChan e) -> m (MsgChan e)
forall a b. (a -> b) -> a -> b
$ TVar (Maybe [PeerMessage e]) -> MsgChan e
forall e. TVar (Maybe [PeerMessage e]) -> MsgChan e
MsgChan (TVar (Maybe [PeerMessage e]) -> MsgChan e)
-> IO (TVar (Maybe [PeerMessage e])) -> IO (MsgChan e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [PeerMessage e] -> IO (TVar (Maybe [PeerMessage e]))
forall a. a -> IO (TVar a)
newTVarIO ([PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just [])


{- | Close a MsgChan. -}
close :: (MonadIO m) => MsgChan e -> m ()
close :: forall (m :: * -> *) e. MonadIO m => MsgChan e -> m ()
close (MsgChan TVar (Maybe [PeerMessage e])
chan) =
  (IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (STM () -> IO ()) -> STM () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM () -> IO ()
forall a. STM a -> IO a
atomically) (TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan Maybe [PeerMessage e]
forall a. Maybe a
Nothing)


stream
  :: MonadIO m
  => Peer
  -> MsgChan e
  -> Stream (Of (Peer, PeerMessage e)) m ()
stream :: forall (m :: * -> *) e.
MonadIO m =>
Peer -> MsgChan e -> Stream (Of (Peer, PeerMessage e)) m ()
stream Peer
self (MsgChan TVar (Maybe [PeerMessage e])
chan) =
  (Stream
  (Of (Peer, PeerMessage e))
  m
  (Stream (Of (Peer, PeerMessage e)) m ())
-> Stream (Of (Peer, PeerMessage e)) m ()
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Stream
   (Of (Peer, PeerMessage e))
   m
   (Stream (Of (Peer, PeerMessage e)) m ())
 -> Stream (Of (Peer, PeerMessage e)) m ())
-> (STM (Stream (Of (Peer, PeerMessage e)) m ())
    -> Stream
         (Of (Peer, PeerMessage e))
         m
         (Stream (Of (Peer, PeerMessage e)) m ()))
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
-> Stream (Of (Peer, PeerMessage e)) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Stream (Of (Peer, PeerMessage e)) m ())
-> Stream
     (Of (Peer, PeerMessage e))
     m
     (Stream (Of (Peer, PeerMessage e)) m ())
forall a. IO a -> Stream (Of (Peer, PeerMessage e)) m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Stream (Of (Peer, PeerMessage e)) m ())
 -> Stream
      (Of (Peer, PeerMessage e))
      m
      (Stream (Of (Peer, PeerMessage e)) m ()))
-> (STM (Stream (Of (Peer, PeerMessage e)) m ())
    -> IO (Stream (Of (Peer, PeerMessage e)) m ()))
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
-> Stream
     (Of (Peer, PeerMessage e))
     m
     (Stream (Of (Peer, PeerMessage e)) m ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM (Stream (Of (Peer, PeerMessage e)) m ())
-> IO (Stream (Of (Peer, PeerMessage e)) m ())
forall a. STM a -> IO a
atomically) (STM (Stream (Of (Peer, PeerMessage e)) m ())
 -> Stream (Of (Peer, PeerMessage e)) m ())
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
-> Stream (Of (Peer, PeerMessage e)) m ()
forall a b. (a -> b) -> a -> b
$
    TVar (Maybe [PeerMessage e]) -> STM (Maybe [PeerMessage e])
forall a. TVar a -> STM a
readTVar TVar (Maybe [PeerMessage e])
chan STM (Maybe [PeerMessage e])
-> (Maybe [PeerMessage e]
    -> STM (Stream (Of (Peer, PeerMessage e)) m ()))
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
forall a b. STM a -> (a -> STM b) -> STM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe [PeerMessage e]
Nothing ->
        {- The stream is closed, so stop.  -}
        Stream (Of (Peer, PeerMessage e)) m ()
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> Stream (Of (Peer, PeerMessage e)) m ()
forall a. a -> Stream (Of (Peer, PeerMessage e)) m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
      Just [] ->
        {- The stream is empty, so wait. -}
        STM (Stream (Of (Peer, PeerMessage e)) m ())
forall a. STM a
retry
      Just [PeerMessage e]
messages -> do
        {-
          The stream is not empty, consume the messages and set the
          stream to empty.
        -}
        TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan ([PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just []) 
        Stream (Of (Peer, PeerMessage e)) m ()
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Stream (Of (Peer, PeerMessage e)) m ()
 -> STM (Stream (Of (Peer, PeerMessage e)) m ()))
-> Stream (Of (Peer, PeerMessage e)) m ()
-> STM (Stream (Of (Peer, PeerMessage e)) m ())
forall a b. (a -> b) -> a -> b
$ do
          (PeerMessage e -> Stream (Of (Peer, PeerMessage e)) m ())
-> [PeerMessage e] -> Stream (Of (Peer, PeerMessage e)) m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((Peer, PeerMessage e) -> Stream (Of (Peer, PeerMessage e)) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
Stream.yield ((Peer, PeerMessage e) -> Stream (Of (Peer, PeerMessage e)) m ())
-> (PeerMessage e -> (Peer, PeerMessage e))
-> PeerMessage e
-> Stream (Of (Peer, PeerMessage e)) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Peer
self,)) [PeerMessage e]
messages
          Peer -> MsgChan e -> Stream (Of (Peer, PeerMessage e)) m ()
forall (m :: * -> *) e.
MonadIO m =>
Peer -> MsgChan e -> Stream (Of (Peer, PeerMessage e)) m ()
stream Peer
self (TVar (Maybe [PeerMessage e]) -> MsgChan e
forall e. TVar (Maybe [PeerMessage e]) -> MsgChan e
MsgChan TVar (Maybe [PeerMessage e])
chan)


{- | Enqueue a message to be sent. Return 'False' if the 'MsgChan' is closed.  -}
enqueueMsg :: (MonadIO m) => MsgChan e -> PeerMessage e -> m Bool
enqueueMsg :: forall (m :: * -> *) e.
MonadIO m =>
MsgChan e -> PeerMessage e -> m Bool
enqueueMsg (MsgChan TVar (Maybe [PeerMessage e])
chan) PeerMessage e
msg =
  m (m Bool) -> m Bool
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (m (m Bool) -> m Bool)
-> (STM (m Bool) -> m (m Bool)) -> STM (m Bool) -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (m Bool) -> m (m Bool)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (m Bool) -> m (m Bool))
-> (STM (m Bool) -> IO (m Bool)) -> STM (m Bool) -> m (m Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM (m Bool) -> IO (m Bool)
forall a. STM a -> IO a
atomically (STM (m Bool) -> m Bool) -> STM (m Bool) -> m Bool
forall a b. (a -> b) -> a -> b
$
    TVar (Maybe [PeerMessage e]) -> STM (Maybe [PeerMessage e])
forall a. TVar a -> STM a
readTVar TVar (Maybe [PeerMessage e])
chan STM (Maybe [PeerMessage e])
-> (Maybe [PeerMessage e] -> STM (m Bool)) -> STM (m Bool)
forall a b. STM a -> (a -> STM b) -> STM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe [PeerMessage e]
Nothing -> m Bool -> STM (m Bool)
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
      Just [PeerMessage e]
msgs -> do
        TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan (
            [PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just ([PeerMessage e] -> Maybe [PeerMessage e])
-> [PeerMessage e] -> Maybe [PeerMessage e]
forall a b. (a -> b) -> a -> b
$ case PeerMessage e
msg of
              PMMerge Diff ClusterName Peer e
_ ->
                PeerMessage e
msg PeerMessage e -> [PeerMessage e] -> [PeerMessage e]
forall a. a -> [a] -> [a]
: (PeerMessage e -> Bool) -> [PeerMessage e] -> [PeerMessage e]
forall a. (a -> Bool) -> [a] -> [a]
filter
                        (\case {PMMerge Diff ClusterName Peer e
_ -> Bool
False; PeerMessage e
_ -> Bool
True})
                        [PeerMessage e]
msgs
              PMFullMerge EventFold ClusterName Peer e
_ ->
                {-
                  Full merges override both older full merges and
                  older partial merges.
                -}
                PeerMessage e
msg PeerMessage e -> [PeerMessage e] -> [PeerMessage e]
forall a. a -> [a] -> [a]
: (PeerMessage e -> Bool) -> [PeerMessage e] -> [PeerMessage e]
forall a. (a -> Bool) -> [a] -> [a]
filter
                        (\case
                          PMMerge Diff ClusterName Peer e
_ -> Bool
False
                          PMFullMerge EventFold ClusterName Peer e
_ -> Bool
False
                          PeerMessage e
_ -> Bool
True
                        )
                        [PeerMessage e]
msgs
              PeerMessage e
_ -> [PeerMessage e]
msgs [PeerMessage e] -> [PeerMessage e] -> [PeerMessage e]
forall a. [a] -> [a] -> [a]
++ [PeerMessage e
msg] 
          )
        m Bool -> STM (m Bool)
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)


{- | The types of messages that can be sent from one peer to another. -}
data PeerMessage e
  = PMMerge (Diff ClusterName Peer e)
    {- ^ Send a powerstate merge. -}
  | PMFullMerge (EventFold ClusterName Peer e)
    {- ^ Send a full merge. -}
  | PMCall Peer MessageId ByteString
    {- ^ Send a user call message from one peer to another. -}
  | PMCast ByteString
    {- ^ Send a user cast message from one peer to another. -}
  | PMCallResponse Peer MessageId ByteString
    {- ^ Send a response to a user call message. -}
  | PMOutputs (Map (EventId Peer) (Output e))
    {- ^ Send outputs to the appropriate recipient. -}
  deriving stock ((forall x. PeerMessage e -> Rep (PeerMessage e) x)
-> (forall x. Rep (PeerMessage e) x -> PeerMessage e)
-> Generic (PeerMessage e)
forall x. Rep (PeerMessage e) x -> PeerMessage e
forall x. PeerMessage e -> Rep (PeerMessage e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall e x. Rep (PeerMessage e) x -> PeerMessage e
forall e x. PeerMessage e -> Rep (PeerMessage e) x
$cfrom :: forall e x. PeerMessage e -> Rep (PeerMessage e) x
from :: forall x. PeerMessage e -> Rep (PeerMessage e) x
$cto :: forall e x. Rep (PeerMessage e) x -> PeerMessage e
to :: forall x. Rep (PeerMessage e) x -> PeerMessage e
Generic)
deriving stock instance
    ( Show e
    , Show (Output e)
    , Show (State e)
    )
  =>
    Show (PeerMessage e)
instance (Binary e, Binary (Output e), Binary (State e)) => Binary (PeerMessage e)


{- | The identification of a node within the legion cluster. -}
newtype Peer = Peer
  { Peer -> Text
unPeer :: Text
  }
  deriving newtype (
    Peer -> Peer -> Bool
(Peer -> Peer -> Bool) -> (Peer -> Peer -> Bool) -> Eq Peer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Peer -> Peer -> Bool
== :: Peer -> Peer -> Bool
$c/= :: Peer -> Peer -> Bool
/= :: Peer -> Peer -> Bool
Eq, Eq Peer
Eq Peer =>
(Peer -> Peer -> Ordering)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Peer)
-> (Peer -> Peer -> Peer)
-> Ord Peer
Peer -> Peer -> Bool
Peer -> Peer -> Ordering
Peer -> Peer -> Peer
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Peer -> Peer -> Ordering
compare :: Peer -> Peer -> Ordering
$c< :: Peer -> Peer -> Bool
< :: Peer -> Peer -> Bool
$c<= :: Peer -> Peer -> Bool
<= :: Peer -> Peer -> Bool
$c> :: Peer -> Peer -> Bool
> :: Peer -> Peer -> Bool
$c>= :: Peer -> Peer -> Bool
>= :: Peer -> Peer -> Bool
$cmax :: Peer -> Peer -> Peer
max :: Peer -> Peer -> Peer
$cmin :: Peer -> Peer -> Peer
min :: Peer -> Peer -> Peer
Ord, Int -> Peer -> ShowS
[Peer] -> ShowS
Peer -> String
(Int -> Peer -> ShowS)
-> (Peer -> String) -> ([Peer] -> ShowS) -> Show Peer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Peer -> ShowS
showsPrec :: Int -> Peer -> ShowS
$cshow :: Peer -> String
show :: Peer -> String
$cshowList :: [Peer] -> ShowS
showList :: [Peer] -> ShowS
Show, [Peer] -> Value
[Peer] -> Encoding
Peer -> Bool
Peer -> Value
Peer -> Encoding
(Peer -> Value)
-> (Peer -> Encoding)
-> ([Peer] -> Value)
-> ([Peer] -> Encoding)
-> (Peer -> Bool)
-> ToJSON Peer
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Peer -> Value
toJSON :: Peer -> Value
$ctoEncoding :: Peer -> Encoding
toEncoding :: Peer -> Encoding
$ctoJSONList :: [Peer] -> Value
toJSONList :: [Peer] -> Value
$ctoEncodingList :: [Peer] -> Encoding
toEncodingList :: [Peer] -> Encoding
$comitField :: Peer -> Bool
omitField :: Peer -> Bool
ToJSON, Get Peer
[Peer] -> Put
Peer -> Put
(Peer -> Put) -> Get Peer -> ([Peer] -> Put) -> Binary Peer
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: Peer -> Put
put :: Peer -> Put
$cget :: Get Peer
get :: Get Peer
$cputList :: [Peer] -> Put
putList :: [Peer] -> Put
Binary, ToJSONKeyFunction [Peer]
ToJSONKeyFunction Peer
ToJSONKeyFunction Peer
-> ToJSONKeyFunction [Peer] -> ToJSONKey Peer
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
$ctoJSONKey :: ToJSONKeyFunction Peer
toJSONKey :: ToJSONKeyFunction Peer
$ctoJSONKeyList :: ToJSONKeyFunction [Peer]
toJSONKeyList :: ToJSONKeyFunction [Peer]
ToJSONKey, Maybe Peer
Value -> Parser [Peer]
Value -> Parser Peer
(Value -> Parser Peer)
-> (Value -> Parser [Peer]) -> Maybe Peer -> FromJSON Peer
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Peer
parseJSON :: Value -> Parser Peer
$cparseJSONList :: Value -> Parser [Peer]
parseJSONList :: Value -> Parser [Peer]
$comittedField :: Maybe Peer
omittedField :: Maybe Peer
FromJSON, FromJSONKeyFunction [Peer]
FromJSONKeyFunction Peer
FromJSONKeyFunction Peer
-> FromJSONKeyFunction [Peer] -> FromJSONKey Peer
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
$cfromJSONKey :: FromJSONKeyFunction Peer
fromJSONKey :: FromJSONKeyFunction Peer
$cfromJSONKeyList :: FromJSONKeyFunction [Peer]
fromJSONKeyList :: FromJSONKeyFunction [Peer]
FromJSONKey,
    Text -> Either Text Peer
ByteString -> Either Text Peer
(Text -> Either Text Peer)
-> (ByteString -> Either Text Peer)
-> (Text -> Either Text Peer)
-> FromHttpApiData Peer
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
$cparseUrlPiece :: Text -> Either Text Peer
parseUrlPiece :: Text -> Either Text Peer
$cparseHeader :: ByteString -> Either Text Peer
parseHeader :: ByteString -> Either Text Peer
$cparseQueryParam :: Text -> Either Text Peer
parseQueryParam :: Text -> Either Text Peer
FromHttpApiData, Peer -> Text
Peer -> ByteString
Peer -> Builder
(Peer -> Text)
-> (Peer -> Builder)
-> (Peer -> ByteString)
-> (Peer -> Text)
-> (Peer -> Builder)
-> ToHttpApiData Peer
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> (a -> Builder)
-> ToHttpApiData a
$ctoUrlPiece :: Peer -> Text
toUrlPiece :: Peer -> Text
$ctoEncodedUrlPiece :: Peer -> Builder
toEncodedUrlPiece :: Peer -> Builder
$ctoHeader :: Peer -> ByteString
toHeader :: Peer -> ByteString
$ctoQueryParam :: Peer -> Text
toQueryParam :: Peer -> Text
$ctoEncodedQueryParam :: Peer -> Builder
toEncodedQueryParam :: Peer -> Builder
ToHttpApiData
  )


{- | The name of a cluster. -}
newtype ClusterName = ClusterName
  { ClusterName -> Text
unClusterName :: Text
  }
  deriving newtype (
    String -> ClusterName
(String -> ClusterName) -> IsString ClusterName
forall a. (String -> a) -> IsString a
$cfromString :: String -> ClusterName
fromString :: String -> ClusterName
IsString, Int -> ClusterName -> ShowS
[ClusterName] -> ShowS
ClusterName -> String
(Int -> ClusterName -> ShowS)
-> (ClusterName -> String)
-> ([ClusterName] -> ShowS)
-> Show ClusterName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClusterName -> ShowS
showsPrec :: Int -> ClusterName -> ShowS
$cshow :: ClusterName -> String
show :: ClusterName -> String
$cshowList :: [ClusterName] -> ShowS
showList :: [ClusterName] -> ShowS
Show, Get ClusterName
[ClusterName] -> Put
ClusterName -> Put
(ClusterName -> Put)
-> Get ClusterName -> ([ClusterName] -> Put) -> Binary ClusterName
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: ClusterName -> Put
put :: ClusterName -> Put
$cget :: Get ClusterName
get :: Get ClusterName
$cputList :: [ClusterName] -> Put
putList :: [ClusterName] -> Put
Binary, ClusterName -> ClusterName -> Bool
(ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool) -> Eq ClusterName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ClusterName -> ClusterName -> Bool
== :: ClusterName -> ClusterName -> Bool
$c/= :: ClusterName -> ClusterName -> Bool
/= :: ClusterName -> ClusterName -> Bool
Eq, [ClusterName] -> Value
[ClusterName] -> Encoding
ClusterName -> Bool
ClusterName -> Value
ClusterName -> Encoding
(ClusterName -> Value)
-> (ClusterName -> Encoding)
-> ([ClusterName] -> Value)
-> ([ClusterName] -> Encoding)
-> (ClusterName -> Bool)
-> ToJSON ClusterName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: ClusterName -> Value
toJSON :: ClusterName -> Value
$ctoEncoding :: ClusterName -> Encoding
toEncoding :: ClusterName -> Encoding
$ctoJSONList :: [ClusterName] -> Value
toJSONList :: [ClusterName] -> Value
$ctoEncodingList :: [ClusterName] -> Encoding
toEncodingList :: [ClusterName] -> Encoding
$comitField :: ClusterName -> Bool
omitField :: ClusterName -> Bool
ToJSON, Maybe ClusterName
Value -> Parser [ClusterName]
Value -> Parser ClusterName
(Value -> Parser ClusterName)
-> (Value -> Parser [ClusterName])
-> Maybe ClusterName
-> FromJSON ClusterName
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser ClusterName
parseJSON :: Value -> Parser ClusterName
$cparseJSONList :: Value -> Parser [ClusterName]
parseJSONList :: Value -> Parser [ClusterName]
$comittedField :: Maybe ClusterName
omittedField :: Maybe ClusterName
FromJSON, Eq ClusterName
Eq ClusterName =>
(ClusterName -> ClusterName -> Ordering)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> ClusterName)
-> (ClusterName -> ClusterName -> ClusterName)
-> Ord ClusterName
ClusterName -> ClusterName -> Bool
ClusterName -> ClusterName -> Ordering
ClusterName -> ClusterName -> ClusterName
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ClusterName -> ClusterName -> Ordering
compare :: ClusterName -> ClusterName -> Ordering
$c< :: ClusterName -> ClusterName -> Bool
< :: ClusterName -> ClusterName -> Bool
$c<= :: ClusterName -> ClusterName -> Bool
<= :: ClusterName -> ClusterName -> Bool
$c> :: ClusterName -> ClusterName -> Bool
> :: ClusterName -> ClusterName -> Bool
$c>= :: ClusterName -> ClusterName -> Bool
>= :: ClusterName -> ClusterName -> Bool
$cmax :: ClusterName -> ClusterName -> ClusterName
max :: ClusterName -> ClusterName -> ClusterName
$cmin :: ClusterName -> ClusterName -> ClusterName
min :: ClusterName -> ClusterName -> ClusterName
Ord, ClusterName -> Text
ClusterName -> ByteString
ClusterName -> Builder
(ClusterName -> Text)
-> (ClusterName -> Builder)
-> (ClusterName -> ByteString)
-> (ClusterName -> Text)
-> (ClusterName -> Builder)
-> ToHttpApiData ClusterName
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> (a -> Builder)
-> ToHttpApiData a
$ctoUrlPiece :: ClusterName -> Text
toUrlPiece :: ClusterName -> Text
$ctoEncodedUrlPiece :: ClusterName -> Builder
toEncodedUrlPiece :: ClusterName -> Builder
$ctoHeader :: ClusterName -> ByteString
toHeader :: ClusterName -> ByteString
$ctoQueryParam :: ClusterName -> Text
toQueryParam :: ClusterName -> Text
$ctoEncodedQueryParam :: ClusterName -> Builder
toEncodedQueryParam :: ClusterName -> Builder
ToHttpApiData,
    Text -> Either Text ClusterName
ByteString -> Either Text ClusterName
(Text -> Either Text ClusterName)
-> (ByteString -> Either Text ClusterName)
-> (Text -> Either Text ClusterName)
-> FromHttpApiData ClusterName
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
$cparseUrlPiece :: Text -> Either Text ClusterName
parseUrlPiece :: Text -> Either Text ClusterName
$cparseHeader :: ByteString -> Either Text ClusterName
parseHeader :: ByteString -> Either Text ClusterName
$cparseQueryParam :: Text -> Either Text ClusterName
parseQueryParam :: Text -> Either Text ClusterName
FromHttpApiData
  )


{- | Message Identifier. -}
data MessageId = M UUID Word64 deriving stock ((forall x. MessageId -> Rep MessageId x)
-> (forall x. Rep MessageId x -> MessageId) -> Generic MessageId
forall x. Rep MessageId x -> MessageId
forall x. MessageId -> Rep MessageId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MessageId -> Rep MessageId x
from :: forall x. MessageId -> Rep MessageId x
$cto :: forall x. Rep MessageId x -> MessageId
to :: forall x. Rep MessageId x -> MessageId
Generic, Int -> MessageId -> ShowS
[MessageId] -> ShowS
MessageId -> String
(Int -> MessageId -> ShowS)
-> (MessageId -> String)
-> ([MessageId] -> ShowS)
-> Show MessageId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MessageId -> ShowS
showsPrec :: Int -> MessageId -> ShowS
$cshow :: MessageId -> String
show :: MessageId -> String
$cshowList :: [MessageId] -> ShowS
showList :: [MessageId] -> ShowS
Show, MessageId -> MessageId -> Bool
(MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool) -> Eq MessageId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MessageId -> MessageId -> Bool
== :: MessageId -> MessageId -> Bool
$c/= :: MessageId -> MessageId -> Bool
/= :: MessageId -> MessageId -> Bool
Eq, Eq MessageId
Eq MessageId =>
(MessageId -> MessageId -> Ordering)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> MessageId)
-> (MessageId -> MessageId -> MessageId)
-> Ord MessageId
MessageId -> MessageId -> Bool
MessageId -> MessageId -> Ordering
MessageId -> MessageId -> MessageId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MessageId -> MessageId -> Ordering
compare :: MessageId -> MessageId -> Ordering
$c< :: MessageId -> MessageId -> Bool
< :: MessageId -> MessageId -> Bool
$c<= :: MessageId -> MessageId -> Bool
<= :: MessageId -> MessageId -> Bool
$c> :: MessageId -> MessageId -> Bool
> :: MessageId -> MessageId -> Bool
$c>= :: MessageId -> MessageId -> Bool
>= :: MessageId -> MessageId -> Bool
$cmax :: MessageId -> MessageId -> MessageId
max :: MessageId -> MessageId -> MessageId
$cmin :: MessageId -> MessageId -> MessageId
min :: MessageId -> MessageId -> MessageId
Ord)
instance Binary MessageId