module ZooKeeper
  ( I.zooVersion
  , I.zooSetDebugLevel

  , zookeeperResInit
  , Res.withResource
  , Res.Resource

  , zooCreate
  , zooSet
  , zooGet
  , zooWatchGet
  , zooGetChildren
  , zooWatchGetChildren
  , zooGetChildren2
  , zooWatchGetChildren2
  , zooDelete
  , zooExists
  , zooWatchExists
  , zooGetAcl

  , zooMulti
  , zooCreateOpInit
  , zooDeleteOpInit
  , zooSetOpInit
  , zooCheckOpInit

  , zooClientID
  , zooState
  , zooRecvTimeout
  , isUnrecoverable

  , zookeeperInit
  , zookeeperClose
  ) where

import           Control.Concurrent       (forkIO, myThreadId, newEmptyMVar,
                                           takeMVar, threadCapability)
import           Control.Exception        (mask_, onException)
import           Control.Monad            (void, when, zipWithM, (<=<))
import           Data.Bifunctor           (first)
import           Data.Maybe               (fromMaybe)
import           Foreign.C                (CInt)
import           Foreign.ForeignPtr       (mallocForeignPtrBytes,
                                           touchForeignPtr, withForeignPtr)
import           Foreign.Ptr              (Ptr, nullPtr, plusPtr)
import           GHC.Conc                 (newStablePtrPrimMVar)
import           GHC.Stack                (HasCallStack, callStack)
import           Z.Data.CBytes            (CBytes)
import qualified Z.Data.CBytes            as CBytes
import qualified Z.Data.Text.Print        as Text
import           Z.Data.Vector            (Bytes)
import qualified Z.Foreign                as Z
import qualified Z.IO.Resource            as Res

import qualified ZooKeeper.Exception      as E
import qualified ZooKeeper.Internal.FFI   as I
import qualified ZooKeeper.Internal.Types as I
import qualified ZooKeeper.Types          as T

-------------------------------------------------------------------------------

-- | Create a resource of handle to used communicate with zookeeper.
zookeeperResInit
  :: HasCallStack
  => CBytes
  -- ^ host, comma separated host:port pairs, each corresponding to a zk
  -- server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
  -> CInt
  -- ^ timeout
  -> Maybe T.ClientID
  -- ^ The id of a previously established session that this client will be
  -- reconnecting to. Pass 'Nothing' if not reconnecting to a previous
  -- session. Clients can access the session id of an established, valid,
  -- connection by calling 'zooGetClientID'. If the session corresponding to
  -- the specified clientid has expired, or if the clientid is invalid for
  -- any reason, the returned 'T.ZHandle' will be invalid -- the 'T.ZHandle'
  -- state will indicate the reason for failure (typically 'T.ZooExpiredSession').
  -> CInt
  -- ^ flags, reserved for future use. Should be set to zero.
  -> Res.Resource T.ZHandle
zookeeperResInit :: CBytes -> CInt -> Maybe ClientID -> CInt -> Resource ZHandle
zookeeperResInit CBytes
host CInt
timeout Maybe ClientID
mclientid CInt
flags =
  IO ZHandle -> (ZHandle -> IO ()) -> Resource ZHandle
forall a. IO a -> (a -> IO ()) -> Resource a
Res.initResource (HasCallStack =>
CBytes -> CInt -> Maybe ClientID -> CInt -> IO ZHandle
CBytes -> CInt -> Maybe ClientID -> CInt -> IO ZHandle
zookeeperInit CBytes
host CInt
timeout Maybe ClientID
mclientid CInt
flags) ZHandle -> IO ()
zookeeperClose

-- | Create a node.
--
-- This method will create a node in ZooKeeper. A node can only be created if
-- it does not already exist. The Create Flags affect the creation of nodes.
-- If 'T.ZooEphemeral' flag is set, the node will automatically get removed if
-- the client session goes away. If the 'T.ZooSequence' flag is set, a unique
-- monotonically increasing sequence number is appended to the path name. The
-- sequence number is always fixed length of 10 digits, 0 padded.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooCreate :: HasCallStack
          => T.ZHandle
          -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
          -> CBytes
          -- ^ The name of the node. Expressed as a file name with slashes
          -- separating ancestors of the node.
          -> Maybe Bytes
          -- ^ The data to be stored in the node.
          -> T.AclVector
          -- ^ The initial ACL of the node. The ACL must not be null or empty.
          -> T.CreateMode
          -- ^ This parameter can be set to 'T.ZooPersistent' for normal create
          -- or an OR of the Create Flags
          -> IO T.StringCompletion
          -- ^ The result when the request completes. One of the
          -- following exceptions will be thrown if error happens:
          --
          -- * ZNONODE the parent node does not exist.
          -- * ZNODEEXISTS the node already exists
          -- * ZNOAUTH the client does not have permission.
          -- * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
zooCreate :: ZHandle
-> CBytes
-> Maybe Bytes
-> AclVector
-> CreateMode
-> IO StringCompletion
zooCreate ZHandle
zh CBytes
path Maybe Bytes
m_value AclVector
acl CreateMode
mode =
  CBytes -> (BA# Word8 -> IO StringCompletion) -> IO StringCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO StringCompletion) -> IO StringCompletion)
-> (BA# Word8 -> IO StringCompletion) -> IO StringCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
    case Maybe Bytes
m_value of
      Just Bytes
value -> Bytes
-> (BA# Word8 -> Int -> Int -> IO StringCompletion)
-> IO StringCompletion
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
Z.withPrimVectorUnsafe Bytes
value ((BA# Word8 -> Int -> Int -> IO StringCompletion)
 -> IO StringCompletion)
-> (BA# Word8 -> Int -> Int -> IO StringCompletion)
-> IO StringCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
val' Int
offset Int
len -> do
        let cfun :: StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt
cfun = ZHandle
-> BA# Word8
-> BA# Word8
-> Int
-> Int
-> AclVector
-> CreateMode
-> StablePtr PrimMVar
-> Int
-> Ptr StringCompletion
-> IO CInt
I.c_hs_zoo_acreate ZHandle
zh BA# Word8
path' BA# Word8
val' Int
offset Int
len AclVector
acl CreateMode
mode
        Either CInt StringCompletion -> IO StringCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StringCompletion -> IO StringCompletion)
-> IO (Either CInt StringCompletion) -> IO StringCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StringCompletion -> IO CInt)
-> (Ptr StringCompletion -> IO StringCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt)
-> IO (Either CInt StringCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StringCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringCompletion -> IO StringCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt
cfun
      Maybe Bytes
Nothing -> do
        let cfun :: StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt
cfun = ZHandle
-> BA# Word8
-> Ptr CChar
-> Int
-> Int
-> AclVector
-> CreateMode
-> StablePtr PrimMVar
-> Int
-> Ptr StringCompletion
-> IO CInt
I.c_hs_zoo_acreate' ZHandle
zh BA# Word8
path' Ptr CChar
forall a. Ptr a
nullPtr Int
0 (-Int
1) AclVector
acl CreateMode
mode
        Either CInt StringCompletion -> IO StringCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StringCompletion -> IO StringCompletion)
-> IO (Either CInt StringCompletion) -> IO StringCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StringCompletion -> IO CInt)
-> (Ptr StringCompletion -> IO StringCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt)
-> IO (Either CInt StringCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StringCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringCompletion -> IO StringCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StringCompletion -> IO CInt
cfun
  where
    csize :: Int
csize = Completion StringCompletion => Int
forall a. Completion a => Int
I.csize @T.StringCompletion

-- | Sets the data associated with a node.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooSet :: HasCallStack
       => T.ZHandle
       -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
       -> CBytes
       -- ^ The name of the node. Expressed as a file name with slashes
       -- separating ancestors of the node.
       -> Maybe Bytes
       -- ^ Data to be written to the node.
       -> Maybe CInt
       -- ^ The expected version of the node. The function will fail
       -- if the actual version of the node does not match the expected version.
       -- If Nothing is used the version check will not take place.
       -> IO T.StatCompletion
       -- ^ The result when the request completes. One of the
       -- following exceptions will be thrown if error happens:
       --
       -- * ZOK operation completed successfully
       -- * ZNONODE the node does not exist.
       -- * ZNOAUTH the client does not have permission.
       -- * ZBADVERSION expected version does not match actual version.
zooSet :: ZHandle -> CBytes -> Maybe Bytes -> Maybe CInt -> IO StatCompletion
zooSet ZHandle
zh CBytes
path Maybe Bytes
m_value Maybe CInt
m_version = CBytes -> (BA# Word8 -> IO StatCompletion) -> IO StatCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO StatCompletion) -> IO StatCompletion)
-> (BA# Word8 -> IO StatCompletion) -> IO StatCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
  let csize :: Int
csize = Completion StatCompletion => Int
forall a. Completion a => Int
I.csize @T.StatCompletion
      version :: CInt
version = CInt -> Maybe CInt -> CInt
forall a. a -> Maybe a -> a
fromMaybe (-CInt
1) Maybe CInt
m_version
  case Maybe Bytes
m_value of
    Just Bytes
value -> Bytes
-> (BA# Word8 -> Int -> Int -> IO StatCompletion)
-> IO StatCompletion
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
Z.withPrimVectorUnsafe Bytes
value ((BA# Word8 -> Int -> Int -> IO StatCompletion)
 -> IO StatCompletion)
-> (BA# Word8 -> Int -> Int -> IO StatCompletion)
-> IO StatCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
val' Int
offset Int
len -> do
      let cfunc :: StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> BA# Word8
-> Int
-> Int
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr StatCompletion
-> IO CInt
I.c_hs_zoo_aset ZHandle
zh BA# Word8
path' BA# Word8
val' Int
offset Int
len CInt
version
      Either CInt StatCompletion -> IO StatCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StatCompletion -> IO StatCompletion)
-> IO (Either CInt StatCompletion) -> IO StatCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StatCompletion -> IO CInt)
-> (Ptr StatCompletion -> IO StatCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt)
-> IO (Either CInt StatCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StatCompletion -> IO StatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc
    Maybe Bytes
Nothing -> do
      let cfunc :: StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> Ptr Word8
-> Int
-> Int
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr StatCompletion
-> IO CInt
I.c_hs_zoo_aset' ZHandle
zh BA# Word8
path' Ptr Word8
forall a. Ptr a
nullPtr Int
0 (-Int
1) CInt
version
      Either CInt StatCompletion -> IO StatCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StatCompletion -> IO StatCompletion)
-> IO (Either CInt StatCompletion) -> IO StatCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StatCompletion -> IO CInt)
-> (Ptr StatCompletion -> IO StatCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt)
-> IO (Either CInt StatCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StatCompletion -> IO StatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc

-- | Gets the data associated with a node.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooGet :: HasCallStack
       => T.ZHandle
       -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
       -> CBytes
       -- ^ The name of the node. Expressed as a file name with slashes
       -- separating ancestors of the node.
       -> IO T.DataCompletion
       -- ^ The result when the request completes. One of the
       -- following exceptions will be thrown if:
       --
       -- * ZNONODE the node does not exist.
       -- * ZNOAUTH the client does not have permission.
zooGet :: ZHandle -> CBytes -> IO DataCompletion
zooGet ZHandle
zh CBytes
path = CBytes -> (BA# Word8 -> IO DataCompletion) -> IO DataCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO DataCompletion) -> IO DataCompletion)
-> (BA# Word8 -> IO DataCompletion) -> IO DataCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
  let csize :: Int
csize = Completion DataCompletion => Int
forall a. Completion a => Int
I.csize @T.DataCompletion
      cfunc :: StablePtr PrimMVar -> Int -> Ptr DataCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr DataCompletion
-> IO CInt
I.c_hs_zoo_aget ZHandle
zh BA# Word8
path' CInt
0
    in Either CInt DataCompletion -> IO DataCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt DataCompletion -> IO DataCompletion)
-> IO (Either CInt DataCompletion) -> IO DataCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr DataCompletion -> IO CInt)
-> (Ptr DataCompletion -> IO DataCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr DataCompletion -> IO CInt)
-> IO (Either CInt DataCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr DataCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr DataCompletion -> IO DataCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr DataCompletion -> IO CInt
cfunc

-- | Gets the data associated with a node.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooWatchGet
  :: HasCallStack
  => T.ZHandle
  -> CBytes
  -> (T.HsWatcherCtx -> IO ())
  -- ^ The watcher callback.
  --
  -- A watch will be set at the server to notify the client if the node changes.
  -> (T.DataCompletion -> IO ())
  -- ^ The result callback when the request completes.
  --
  -- One of the following exceptions will be thrown if:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
  -> IO ()
zooWatchGet :: ZHandle
-> CBytes
-> (HsWatcherCtx -> IO ())
-> (DataCompletion -> IO ())
-> IO ()
zooWatchGet ZHandle
zh CBytes
path HsWatcherCtx -> IO ()
watchfn DataCompletion -> IO ()
datafn = CBytes -> (BA# Word8 -> IO ()) -> IO ()
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ()) -> IO ()) -> (BA# Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
  let csize :: Int
csize = Completion DataCompletion => Int
forall a. Completion a => Int
I.csize @T.DataCompletion
      watchfn' :: Either CInt HsWatcherCtx -> IO ()
watchfn' = HsWatcherCtx -> IO ()
watchfn (HsWatcherCtx -> IO ())
-> (Either CInt HsWatcherCtx -> IO HsWatcherCtx)
-> Either CInt HsWatcherCtx
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt HsWatcherCtx -> IO HsWatcherCtx
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
      datafn' :: Either CInt DataCompletion -> IO ()
datafn' = DataCompletion -> IO ()
datafn (DataCompletion -> IO ())
-> (Either CInt DataCompletion -> IO DataCompletion)
-> Either CInt DataCompletion
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt DataCompletion -> IO DataCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
   in Int
-> (Ptr HsWatcherCtx -> IO CInt)
-> (Ptr HsWatcherCtx -> IO HsWatcherCtx)
-> (Either CInt HsWatcherCtx -> IO ())
-> Int
-> (Ptr DataCompletion -> IO CInt)
-> (Ptr DataCompletion -> IO DataCompletion)
-> (Either CInt DataCompletion -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar
    -> Int
    -> Ptr HsWatcherCtx
    -> Ptr DataCompletion
    -> IO CInt)
-> IO ()
forall a b.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (Either CInt a -> IO ())
-> Int
-> (Ptr b -> IO CInt)
-> (Ptr b -> IO b)
-> (Either CInt b -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar -> Int -> Ptr a -> Ptr b -> IO CInt)
-> IO ()
I.withZKAsync2
        Int
I.hsWatcherCtxSize (\Ptr HsWatcherCtx
_ -> CInt -> IO CInt
forall (m :: * -> *) a. Monad m => a -> m a
return CInt
E.CZOK) Ptr HsWatcherCtx -> IO HsWatcherCtx
I.peekHsWatcherCtx Either CInt HsWatcherCtx -> IO ()
watchfn'
        Int
csize Ptr DataCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr DataCompletion -> IO DataCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData Either CInt DataCompletion -> IO ()
datafn'
        (ZHandle
-> BA# Word8
-> StablePtr PrimMVar
-> StablePtr PrimMVar
-> Int
-> Ptr HsWatcherCtx
-> Ptr DataCompletion
-> IO CInt
I.c_hs_zoo_awget ZHandle
zh BA# Word8
path')

-- | Delete a node in zookeeper.
--
-- Throw one of the following exceptions on failure:
--
-- * 'E.ZBADARGUMENTS' - invalid input parameters
-- * 'E.ZINVALIDSTATE' - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * 'E.ZMARSHALLINGERROR' - failed to marshall a request; possibly, out of memory
--
-- Throw one of the following exceptions if the request completes failed:
--
-- * ZNONODE      the node does not exist.
-- * ZNOAUTH      the client does not have permission.
-- * ZBADVERSION  expected version does not match actual version.
-- * ZNOTEMPTY    children are present; node cannot be deleted.
zooDelete :: HasCallStack
          => T.ZHandle
          -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
          -> CBytes
          -- ^ The name of the node. Expressed as a file name with slashes
          -- separating ancestors of the node.
          -> Maybe CInt
          -- ^ The expected version of the node. The function will fail
          -- if the actual version of the node does not match the expected version.
          -- If Nothing is used the version check will not take place.
          -> IO ()
zooDelete :: ZHandle -> CBytes -> Maybe CInt -> IO ()
zooDelete ZHandle
zh CBytes
path Maybe CInt
m_version = CBytes -> (BA# Word8 -> IO ()) -> IO ()
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ()) -> IO ()) -> (BA# Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
  let csize :: Int
csize = Completion VoidCompletion => Int
forall a. Completion a => Int
I.csize @T.VoidCompletion
      cfunc :: StablePtr PrimMVar -> Int -> Ptr VoidCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr VoidCompletion
-> IO CInt
I.c_hs_zoo_adelete ZHandle
zh BA# Word8
path' CInt
version
      version :: CInt
version = CInt -> Maybe CInt -> CInt
forall a. a -> Maybe a -> a
fromMaybe (-CInt
1) Maybe CInt
m_version
   in IO VoidCompletion -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO VoidCompletion -> IO ()) -> IO VoidCompletion -> IO ()
forall a b. (a -> b) -> a -> b
$ Either CInt VoidCompletion -> IO VoidCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt VoidCompletion -> IO VoidCompletion)
-> IO (Either CInt VoidCompletion) -> IO VoidCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr VoidCompletion -> IO CInt)
-> (Ptr VoidCompletion -> IO VoidCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr VoidCompletion -> IO CInt)
-> IO (Either CInt VoidCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr VoidCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr VoidCompletion -> IO VoidCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr VoidCompletion -> IO CInt
cfunc

-- | Checks the existence of a node in zookeeper.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooExists :: HasCallStack
          => T.ZHandle
          -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
          -> CBytes
          -- ^ The name of the node. Expressed as a file name with slashes
          -- separating ancestors of the node.
          -> IO (Maybe T.StatCompletion)
          -- ^ The result when the request completes. Nothing means
          -- the node does not exist.
          --
          -- One of the following exceptions will be thrown if error happens:
          --
          -- * ZNOAUTH the client does not have permission.
zooExists :: ZHandle -> CBytes -> IO (Maybe StatCompletion)
zooExists ZHandle
zh CBytes
path =
  CBytes
-> (BA# Word8 -> IO (Maybe StatCompletion))
-> IO (Maybe StatCompletion)
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO (Maybe StatCompletion))
 -> IO (Maybe StatCompletion))
-> (BA# Word8 -> IO (Maybe StatCompletion))
-> IO (Maybe StatCompletion)
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
    let csize :: Int
csize = Completion StatCompletion => Int
forall a. Completion a => Int
I.csize @T.StatCompletion
        cfunc :: StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr StatCompletion
-> IO CInt
I.c_hs_zoo_aexists ZHandle
zh BA# Word8
path' CInt
0
     in (CInt -> Bool)
-> Either CInt StatCompletion -> IO (Maybe StatCompletion)
forall a.
HasCallStack =>
(CInt -> Bool) -> Either CInt a -> IO (Maybe a)
E.throwZooErrorIfLeft' (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
E.CZNONODE) (Either CInt StatCompletion -> IO (Maybe StatCompletion))
-> IO (Either CInt StatCompletion) -> IO (Maybe StatCompletion)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StatCompletion -> IO CInt)
-> (Ptr StatCompletion -> IO StatCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt)
-> IO (Either CInt StatCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StatCompletion -> IO StatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StatCompletion -> IO CInt
cfunc

-- | Checks the existence of a node in zookeeper.
--
-- This function is similar to 'zooExists' except it allows one specify
-- a watcher object. The function will be called once the watch has fired.
--
-- Note that the watch will fire both when the node is created and its associated
-- data is set.
--
-- Note that there is only one thread for triggering callbacks. Which means this
-- function will first block on the completion, and then wating on the watcher.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooWatchExists
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> (T.HsWatcherCtx -> IO ())
  -- ^ The watcher callback.
  --
  -- A watch will set on the specified znode on the server. The watch will be
  -- set even if the node does not exist. This allows clients to watch for
  -- nodes to appear.
  -> (Maybe T.StatCompletion -> IO ())
  -- ^ The result callback when the request completes. Nothing means
  -- the node does not exist.
  --
  -- One of the following exceptions will be thrown if error happens:
  --
  -- * ZNOAUTH the client does not have permission.
  -> IO ()
zooWatchExists :: ZHandle
-> CBytes
-> (HsWatcherCtx -> IO ())
-> (Maybe StatCompletion -> IO ())
-> IO ()
zooWatchExists ZHandle
zh CBytes
path HsWatcherCtx -> IO ()
watchfn Maybe StatCompletion -> IO ()
statfn =
  let csize :: Int
csize = Completion StatCompletion => Int
forall a. Completion a => Int
I.csize @T.StatCompletion
      watchfn' :: Either CInt HsWatcherCtx -> IO ()
watchfn' = HsWatcherCtx -> IO ()
watchfn (HsWatcherCtx -> IO ())
-> (Either CInt HsWatcherCtx -> IO HsWatcherCtx)
-> Either CInt HsWatcherCtx
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt HsWatcherCtx -> IO HsWatcherCtx
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
      statfn' :: Either CInt StatCompletion -> IO ()
statfn' = Maybe StatCompletion -> IO ()
statfn (Maybe StatCompletion -> IO ())
-> (Either CInt StatCompletion -> IO (Maybe StatCompletion))
-> Either CInt StatCompletion
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (CInt -> Bool)
-> Either CInt StatCompletion -> IO (Maybe StatCompletion)
forall a.
HasCallStack =>
(CInt -> Bool) -> Either CInt a -> IO (Maybe a)
E.throwZooErrorIfLeft' (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
E.CZNONODE)
   in CBytes -> (BA# Word8 -> IO ()) -> IO ()
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ()) -> IO ()) -> (BA# Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
        Int
-> (Ptr HsWatcherCtx -> IO CInt)
-> (Ptr HsWatcherCtx -> IO HsWatcherCtx)
-> (Either CInt HsWatcherCtx -> IO ())
-> Int
-> (Ptr StatCompletion -> IO CInt)
-> (Ptr StatCompletion -> IO StatCompletion)
-> (Either CInt StatCompletion -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar
    -> Int
    -> Ptr HsWatcherCtx
    -> Ptr StatCompletion
    -> IO CInt)
-> IO ()
forall a b.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (Either CInt a -> IO ())
-> Int
-> (Ptr b -> IO CInt)
-> (Ptr b -> IO b)
-> (Either CInt b -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar -> Int -> Ptr a -> Ptr b -> IO CInt)
-> IO ()
I.withZKAsync2
          Int
I.hsWatcherCtxSize (\Ptr HsWatcherCtx
_ -> CInt -> IO CInt
forall (m :: * -> *) a. Monad m => a -> m a
return CInt
E.CZOK) Ptr HsWatcherCtx -> IO HsWatcherCtx
I.peekHsWatcherCtx Either CInt HsWatcherCtx -> IO ()
watchfn'
          Int
csize Ptr StatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StatCompletion -> IO StatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData Either CInt StatCompletion -> IO ()
statfn'
          (ZHandle
-> BA# Word8
-> StablePtr PrimMVar
-> StablePtr PrimMVar
-> Int
-> Ptr HsWatcherCtx
-> Ptr StatCompletion
-> IO CInt
I.c_hs_zoo_awexists ZHandle
zh BA# Word8
path')

-- | Lists the children of a node.
--
-- Throw one of the following exceptions on failure:
--
-- * ZBADARGUMENTS - invalid input parameters
-- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooGetChildren
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> IO T.StringsCompletion
  -- ^ The result when the request completes.
  --
  -- Throw one of the following exceptions if the request completes failed:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
zooGetChildren :: ZHandle -> CBytes -> IO StringsCompletion
zooGetChildren ZHandle
zh CBytes
path = CBytes
-> (BA# Word8 -> IO StringsCompletion) -> IO StringsCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO StringsCompletion) -> IO StringsCompletion)
-> (BA# Word8 -> IO StringsCompletion) -> IO StringsCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
  let csize :: Int
csize = Completion StringsCompletion => Int
forall a. Completion a => Int
I.csize @T.StringsCompletion
      cfunc :: StablePtr PrimMVar -> Int -> Ptr StringsCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr StringsCompletion
-> IO CInt
I.c_hs_zoo_aget_children ZHandle
zh BA# Word8
path' CInt
0
    in Either CInt StringsCompletion -> IO StringsCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StringsCompletion -> IO StringsCompletion)
-> IO (Either CInt StringsCompletion) -> IO StringsCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StringsCompletion -> IO CInt)
-> (Ptr StringsCompletion -> IO StringsCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr StringsCompletion -> IO CInt)
-> IO (Either CInt StringsCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StringsCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringsCompletion -> IO StringsCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StringsCompletion -> IO CInt
cfunc

-- | Lists the children of a node.
--
-- This function is similar to 'zooGetChildren' except it allows one specify
-- a watcher object.
--
-- Note that there is only one thread for triggering callbacks. Which means this
-- function will first block on the completion, and then wating on the watcher.
--
-- Throw one of the following exceptions on failure:
--
-- ZBADARGUMENTS - invalid input parameters
-- ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooWatchGetChildren
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> (T.HsWatcherCtx -> IO ())
  -- ^ The watcher callback. A watch will be set at the server to notify
  --  the client if the node changes.
  -> (T.StringsCompletion -> IO ())
  -- ^ The result callback when the request completes.
  --
  -- One of the following exceptions will be thrown if error happens:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
  -> IO ()
zooWatchGetChildren :: ZHandle
-> CBytes
-> (HsWatcherCtx -> IO ())
-> (StringsCompletion -> IO ())
-> IO ()
zooWatchGetChildren ZHandle
zh CBytes
path HsWatcherCtx -> IO ()
watchfn StringsCompletion -> IO ()
stringsfn =
  let csize :: Int
csize = Completion StringsCompletion => Int
forall a. Completion a => Int
I.csize @T.StringsCompletion
      watchfn' :: Either CInt HsWatcherCtx -> IO ()
watchfn' = HsWatcherCtx -> IO ()
watchfn (HsWatcherCtx -> IO ())
-> (Either CInt HsWatcherCtx -> IO HsWatcherCtx)
-> Either CInt HsWatcherCtx
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt HsWatcherCtx -> IO HsWatcherCtx
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
      stringsfn' :: Either CInt StringsCompletion -> IO ()
stringsfn' = StringsCompletion -> IO ()
stringsfn (StringsCompletion -> IO ())
-> (Either CInt StringsCompletion -> IO StringsCompletion)
-> Either CInt StringsCompletion
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt StringsCompletion -> IO StringsCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
   in CBytes -> (BA# Word8 -> IO ()) -> IO ()
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ()) -> IO ()) -> (BA# Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
        Int
-> (Ptr HsWatcherCtx -> IO CInt)
-> (Ptr HsWatcherCtx -> IO HsWatcherCtx)
-> (Either CInt HsWatcherCtx -> IO ())
-> Int
-> (Ptr StringsCompletion -> IO CInt)
-> (Ptr StringsCompletion -> IO StringsCompletion)
-> (Either CInt StringsCompletion -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar
    -> Int
    -> Ptr HsWatcherCtx
    -> Ptr StringsCompletion
    -> IO CInt)
-> IO ()
forall a b.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (Either CInt a -> IO ())
-> Int
-> (Ptr b -> IO CInt)
-> (Ptr b -> IO b)
-> (Either CInt b -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar -> Int -> Ptr a -> Ptr b -> IO CInt)
-> IO ()
I.withZKAsync2
          Int
I.hsWatcherCtxSize (\Ptr HsWatcherCtx
_ -> CInt -> IO CInt
forall (m :: * -> *) a. Monad m => a -> m a
return CInt
E.CZOK) Ptr HsWatcherCtx -> IO HsWatcherCtx
I.peekHsWatcherCtx Either CInt HsWatcherCtx -> IO ()
watchfn'
          Int
csize Ptr StringsCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringsCompletion -> IO StringsCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData Either CInt StringsCompletion -> IO ()
stringsfn'
          (ZHandle
-> BA# Word8
-> StablePtr PrimMVar
-> StablePtr PrimMVar
-> Int
-> Ptr HsWatcherCtx
-> Ptr StringsCompletion
-> IO CInt
I.c_hs_zoo_awget_children ZHandle
zh BA# Word8
path')

-- | Lists the children of a node, and get the parent stat.
--
-- This function is new in version 3.3.0
--
-- Throw one of the following exceptions on failure:
--
-- * 'E.ZBADARGUMENTS' - invalid input parameters
-- * 'E.ZINVALIDSTATE' - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * 'E.ZMARSHALLINGERROR' - failed to marshall a request; possibly, out of memory
zooGetChildren2
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> IO T.StringsStatCompletion
  -- ^ The result when the request completes.
  --
  -- Throw one of the following exceptions if the request completes failed:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
zooGetChildren2 :: ZHandle -> CBytes -> IO StringsStatCompletion
zooGetChildren2 ZHandle
zh CBytes
path = CBytes
-> (BA# Word8 -> IO StringsStatCompletion)
-> IO StringsStatCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO StringsStatCompletion)
 -> IO StringsStatCompletion)
-> (BA# Word8 -> IO StringsStatCompletion)
-> IO StringsStatCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
  let csize :: Int
csize = Completion StringsStatCompletion => Int
forall a. Completion a => Int
I.csize @T.StringsStatCompletion
      cfunc :: StablePtr PrimMVar -> Int -> Ptr StringsStatCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> CInt
-> StablePtr PrimMVar
-> Int
-> Ptr StringsStatCompletion
-> IO CInt
I.c_hs_zoo_aget_children2 ZHandle
zh BA# Word8
path' CInt
0
    in Either CInt StringsStatCompletion -> IO StringsStatCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt StringsStatCompletion -> IO StringsStatCompletion)
-> IO (Either CInt StringsStatCompletion)
-> IO StringsStatCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr StringsStatCompletion -> IO CInt)
-> (Ptr StringsStatCompletion -> IO StringsStatCompletion)
-> (StablePtr PrimMVar
    -> Int -> Ptr StringsStatCompletion -> IO CInt)
-> IO (Either CInt StringsStatCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr StringsStatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringsStatCompletion -> IO StringsStatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr StringsStatCompletion -> IO CInt
cfunc

-- | Lists the children of a node, and get the parent stat.
--
-- This function is new in version 3.3.0
--
-- Note that there is only one thread for triggering callbacks. Which means this
-- function will first block on the completion, and then wating on the watcher.
--
-- Throw one of the following exceptions on failure:
--
-- * 'E.ZBADARGUMENTS' - invalid input parameters
-- * 'E.ZINVALIDSTATE' - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- * 'E.ZMARSHALLINGERROR' - failed to marshall a request; possibly, out of memory
zooWatchGetChildren2
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> (T.HsWatcherCtx -> IO ())
  -- ^ The watcher callback. A watch will be set at the server to notify
  --  the client if the node changes.
  -> (T.StringsStatCompletion -> IO ())
  -- ^ The result callback when the request completes.
  --
  -- One of the following exceptions will be thrown if error happens:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
  -> IO ()
zooWatchGetChildren2 :: ZHandle
-> CBytes
-> (HsWatcherCtx -> IO ())
-> (StringsStatCompletion -> IO ())
-> IO ()
zooWatchGetChildren2 ZHandle
zh CBytes
path HsWatcherCtx -> IO ()
watchfn StringsStatCompletion -> IO ()
strsStatfn =
  let csize :: Int
csize = Completion StringsStatCompletion => Int
forall a. Completion a => Int
I.csize @T.StringsStatCompletion
      watchfn' :: Either CInt HsWatcherCtx -> IO ()
watchfn' = HsWatcherCtx -> IO ()
watchfn (HsWatcherCtx -> IO ())
-> (Either CInt HsWatcherCtx -> IO HsWatcherCtx)
-> Either CInt HsWatcherCtx
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt HsWatcherCtx -> IO HsWatcherCtx
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
      stringsfn' :: Either CInt StringsStatCompletion -> IO ()
stringsfn' = StringsStatCompletion -> IO ()
strsStatfn (StringsStatCompletion -> IO ())
-> (Either CInt StringsStatCompletion -> IO StringsStatCompletion)
-> Either CInt StringsStatCompletion
-> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either CInt StringsStatCompletion -> IO StringsStatCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft
   in CBytes -> (BA# Word8 -> IO ()) -> IO ()
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ()) -> IO ()) -> (BA# Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
        Int
-> (Ptr HsWatcherCtx -> IO CInt)
-> (Ptr HsWatcherCtx -> IO HsWatcherCtx)
-> (Either CInt HsWatcherCtx -> IO ())
-> Int
-> (Ptr StringsStatCompletion -> IO CInt)
-> (Ptr StringsStatCompletion -> IO StringsStatCompletion)
-> (Either CInt StringsStatCompletion -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar
    -> Int
    -> Ptr HsWatcherCtx
    -> Ptr StringsStatCompletion
    -> IO CInt)
-> IO ()
forall a b.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (Either CInt a -> IO ())
-> Int
-> (Ptr b -> IO CInt)
-> (Ptr b -> IO b)
-> (Either CInt b -> IO ())
-> (StablePtr PrimMVar
    -> StablePtr PrimMVar -> Int -> Ptr a -> Ptr b -> IO CInt)
-> IO ()
I.withZKAsync2
          Int
I.hsWatcherCtxSize (\Ptr HsWatcherCtx
_ -> CInt -> IO CInt
forall (m :: * -> *) a. Monad m => a -> m a
return CInt
E.CZOK) Ptr HsWatcherCtx -> IO HsWatcherCtx
I.peekHsWatcherCtx Either CInt HsWatcherCtx -> IO ()
watchfn'
          Int
csize Ptr StringsStatCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr StringsStatCompletion -> IO StringsStatCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData Either CInt StringsStatCompletion -> IO ()
stringsfn'
          (ZHandle
-> BA# Word8
-> StablePtr PrimMVar
-> StablePtr PrimMVar
-> Int
-> Ptr HsWatcherCtx
-> Ptr StringsStatCompletion
-> IO CInt
I.c_hs_zoo_awget_children2 ZHandle
zh BA# Word8
path')

-- | Gets the acl associated with a node.
--
-- Throw one of the following exceptions on failure:
--
-- ZBADARGUMENTS - invalid input parameters
-- ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
-- ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
zooGetAcl
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> IO T.AclCompletion
  -- ^ The result when the request completes.
  --
  -- Throw one of the following exceptions if the request completes failed:
  --
  -- * ZNONODE the node does not exist.
  -- * ZNOAUTH the client does not have permission.
zooGetAcl :: ZHandle -> CBytes -> IO AclCompletion
zooGetAcl ZHandle
zh CBytes
path = CBytes -> (BA# Word8 -> IO AclCompletion) -> IO AclCompletion
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO AclCompletion) -> IO AclCompletion)
-> (BA# Word8 -> IO AclCompletion) -> IO AclCompletion
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
  let csize :: Int
csize = Completion AclCompletion => Int
forall a. Completion a => Int
I.csize @T.AclCompletion
      cfunc :: StablePtr PrimMVar -> Int -> Ptr AclCompletion -> IO CInt
cfunc = ZHandle
-> BA# Word8
-> StablePtr PrimMVar
-> Int
-> Ptr AclCompletion
-> IO CInt
I.c_hs_zoo_aget_acl ZHandle
zh BA# Word8
path'
   in Either CInt AclCompletion -> IO AclCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt AclCompletion -> IO AclCompletion)
-> IO (Either CInt AclCompletion) -> IO AclCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int
-> (Ptr AclCompletion -> IO CInt)
-> (Ptr AclCompletion -> IO AclCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr AclCompletion -> IO CInt)
-> IO (Either CInt AclCompletion)
forall a.
HasCallStack =>
Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync Int
csize Ptr AclCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr AclCompletion -> IO AclCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData StablePtr PrimMVar -> Int -> Ptr AclCompletion -> IO CInt
cfunc

-------------------------------------------------------------------------------

-- | Atomically commits multiple zookeeper operations.
--
-- Throw exceptions if error happened, the exception will be any of the operations
-- supported by a multi op, see 'zooCreate', 'zooDelete' and 'zooSet'.
zooMulti
  :: HasCallStack
  => T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> [T.ZooOp]
  -- ^ An list of operations to commit
  -> IO [T.ZooOpResult]
zooMulti :: ZHandle -> [ZooOp] -> IO [ZooOpResult]
zooMulti ZHandle
zh [ZooOp]
ops = do
  let len :: Int
len = [ZooOp] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ZooOp]
ops
      completionSize :: Int
completionSize = Completion VoidCompletion => Int
forall a. Completion a => Int
I.csize @T.VoidCompletion
      chunkPtr :: Ptr a -> Int -> [Ptr b]
chunkPtr Ptr a
ptr Int
size = (Int -> Ptr b) -> [Int] -> [Ptr b]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> Ptr a
ptr Ptr a -> Int -> Ptr b
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
size)) [Int
0..Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]

  mbai :: MutableByteArray RealWorld
mbai@(Z.MutableByteArray MutableByteArray# RealWorld
mbai#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
Z.newPinnedByteArray (Int
I.zooOpSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
len)
  mbar :: MutableByteArray RealWorld
mbar@(Z.MutableByteArray MutableByteArray# RealWorld
mbar#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
Z.newPinnedByteArray (Int
I.zooOpResultSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
len)
  let ptr :: Ptr Word8
ptr = MutableByteArray RealWorld -> Ptr Word8
forall s. MutableByteArray s -> Ptr Word8
Z.mutableByteArrayContents MutableByteArray RealWorld
mbai
      ptr_result :: Ptr Word8
ptr_result = MutableByteArray RealWorld -> Ptr Word8
forall s. MutableByteArray s -> Ptr Word8
Z.mutableByteArrayContents MutableByteArray RealWorld
mbar

  [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
res <- ((ZooOp, Ptr CZooOp)
 -> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes))
-> [(ZooOp, Ptr CZooOp)]
-> IO [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (ZooOp, Ptr CZooOp)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
initOp ([(ZooOp, Ptr CZooOp)]
 -> IO [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)])
-> [(ZooOp, Ptr CZooOp)]
-> IO [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
forall a b. (a -> b) -> a -> b
$ [ZooOp] -> [Ptr CZooOp] -> [(ZooOp, Ptr CZooOp)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ZooOp]
ops (Ptr Word8 -> Int -> [Ptr CZooOp]
forall a b. Ptr a -> Int -> [Ptr b]
chunkPtr Ptr Word8
ptr Int
I.zooOpSize)
  Either CInt VoidCompletion -> IO VoidCompletion
forall a. HasCallStack => Either CInt a -> IO a
E.throwZooErrorIfLeft (Either CInt VoidCompletion -> IO VoidCompletion)
-> IO (Either CInt VoidCompletion) -> IO VoidCompletion
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
    TouchListBytes
-> Int
-> (Ptr VoidCompletion -> IO CInt)
-> (Ptr VoidCompletion -> IO VoidCompletion)
-> (StablePtr PrimMVar -> Int -> Ptr VoidCompletion -> IO CInt)
-> IO (Either CInt VoidCompletion)
forall a.
HasCallStack =>
TouchListBytes
-> Int
-> (Ptr a -> IO CInt)
-> (Ptr a -> IO a)
-> (StablePtr PrimMVar -> Int -> Ptr a -> IO CInt)
-> IO (Either CInt a)
I.withZKAsync' (((Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
 -> TouchListBytes)
-> [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
-> TouchListBytes
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
-> TouchListBytes
forall a b. (a, b) -> b
snd [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
res) Int
completionSize Ptr VoidCompletion -> IO CInt
forall a. Completion a => Ptr a -> IO CInt
I.peekRet Ptr VoidCompletion -> IO VoidCompletion
forall a. Completion a => Ptr a -> IO a
I.peekData
                   (ZHandle
-> CInt
-> MutableByteArray# RealWorld
-> MutableByteArray# RealWorld
-> StablePtr PrimMVar
-> Int
-> Ptr VoidCompletion
-> IO CInt
I.c_hs_zoo_amulti ZHandle
zh (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) MutableByteArray# RealWorld
mbai# MutableByteArray# RealWorld
mbar#)
  ((Ptr CZooOpResult -> IO ZooOpResult)
 -> Ptr CZooOpResult -> IO ZooOpResult)
-> [Ptr CZooOpResult -> IO ZooOpResult]
-> [Ptr CZooOpResult]
-> IO [ZooOpResult]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (Ptr CZooOpResult -> IO ZooOpResult)
-> Ptr CZooOpResult -> IO ZooOpResult
forall a b. (a -> b) -> a -> b
($) (((Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
 -> Ptr CZooOpResult -> IO ZooOpResult)
-> [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
-> [Ptr CZooOpResult -> IO ZooOpResult]
forall a b. (a -> b) -> [a] -> [b]
map (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
-> Ptr CZooOpResult -> IO ZooOpResult
forall a b. (a, b) -> a
fst [(Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)]
res) (Ptr Word8 -> Int -> [Ptr CZooOpResult]
forall a b. Ptr a -> Int -> [Ptr b]
chunkPtr Ptr Word8
ptr_result Int
I.zooOpResultSize)

-- | Internal helper function to set zoo op.
initOp :: (I.ZooOp, Ptr I.CZooOp)
       -> IO (Ptr I.CZooOpResult -> IO T.ZooOpResult, I.TouchListBytes)
-- we know that the size of this list is larger than one
initOp :: (ZooOp, Ptr CZooOp)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
initOp (I.ZooCreateOp Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes)
f, Ptr CZooOp
p) = (MutableByteArray RealWorld -> Ptr CZooOpResult -> IO ZooOpResult)
-> (MutableByteArray RealWorld, TouchListBytes)
-> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first MutableByteArray RealWorld -> Ptr CZooOpResult -> IO ZooOpResult
I.peekZooCreateOpResult ((MutableByteArray RealWorld, TouchListBytes)
 -> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes)
f Ptr CZooOp
p
initOp (I.ZooDeleteOp Ptr CZooOp -> IO ((), TouchListBytes)
f, Ptr CZooOp
p) = (() -> Ptr CZooOpResult -> IO ZooOpResult)
-> ((), TouchListBytes)
-> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((Ptr CZooOpResult -> IO ZooOpResult)
-> () -> Ptr CZooOpResult -> IO ZooOpResult
forall a b. a -> b -> a
const Ptr CZooOpResult -> IO ZooOpResult
I.peekZooDeleteOpResult) (((), TouchListBytes)
 -> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes))
-> IO ((), TouchListBytes)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Ptr CZooOp -> IO ((), TouchListBytes)
f Ptr CZooOp
p
initOp (I.ZooSetOp    Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes)
f, Ptr CZooOp
p) = (MutableByteArray RealWorld -> Ptr CZooOpResult -> IO ZooOpResult)
-> (MutableByteArray RealWorld, TouchListBytes)
-> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first MutableByteArray RealWorld -> Ptr CZooOpResult -> IO ZooOpResult
I.peekZooSetOpResult ((MutableByteArray RealWorld, TouchListBytes)
 -> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes)
f Ptr CZooOp
p
initOp (I.ZooCheckOp  Ptr CZooOp -> IO ((), TouchListBytes)
f, Ptr CZooOp
p) = (() -> Ptr CZooOpResult -> IO ZooOpResult)
-> ((), TouchListBytes)
-> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((Ptr CZooOpResult -> IO ZooOpResult)
-> () -> Ptr CZooOpResult -> IO ZooOpResult
forall a b. a -> b -> a
const Ptr CZooOpResult -> IO ZooOpResult
I.peekZooCheckOpResult) (((), TouchListBytes)
 -> (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes))
-> IO ((), TouchListBytes)
-> IO (Ptr CZooOpResult -> IO ZooOpResult, TouchListBytes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Ptr CZooOp -> IO ((), TouchListBytes)
f Ptr CZooOp
p
{-# INLINE initOp #-}

-- | Init create op.
--
-- This function initializes a 'T.ZooOp' with the arguments for a ZOO_CREATE_OP.
zooCreateOpInit
  :: CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> Maybe Bytes
  -- ^ The data to be stored in the node.
  -> CInt
  -- ^ The max buffer size of the created new node path (this might be
  -- different than the supplied path because of the 'T.ZooSequence' flag).
  -- If this size is 0,
  --
  -- Note: we do NOT check if the size is non-negative.
  --
  -- If the path of the new node exceeds the buffer size, the path string will
  -- be truncated to fit. The actual path of the new node in the server will
  -- not be affected by the truncation.
  -> T.AclVector
  -- ^ The initial ACL of the node. The ACL must not be null or empty.
  -> T.CreateMode
  -- ^ This parameter can be set to 'T.ZooPersistent' for normal create
  -- or an OR of the Create Flags
  -> T.ZooOp
zooCreateOpInit :: CBytes -> Maybe Bytes -> CInt -> AclVector -> CreateMode -> ZooOp
zooCreateOpInit CBytes
path Maybe Bytes
m_value CInt
buflen AclVector
acl CreateMode
mode = (Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
-> ZooOp
I.ZooCreateOp ((Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
 -> ZooOp)
-> (Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
-> ZooOp
forall a b. (a -> b) -> a -> b
$ \Ptr CZooOp
op -> do
  let buflen' :: CInt
buflen' = CInt
buflen CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
+ CInt
1  -- including space for the null terminator
  CBytes
-> (BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> (BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
    mba :: MutableByteArray RealWorld
mba@(Z.MutableByteArray MutableByteArray# RealWorld
mba#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
Z.newPinnedByteArray (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
buflen')
    case Maybe Bytes
m_value of
        Just Bytes
value -> Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
Z.withPrimVectorUnsafe Bytes
value ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
val' Int
offset Int
len ->
          Ptr CZooOp
-> BA# Word8
-> BA# Word8
-> Int
-> Int
-> AclVector
-> CreateMode
-> MutableByteArray# RealWorld
-> CInt
-> IO ()
I.c_hs_zoo_create_op_init Ptr CZooOp
op BA# Word8
path' BA# Word8
val' Int
offset Int
len AclVector
acl CreateMode
mode MutableByteArray# RealWorld
mba# CInt
buflen'
        Maybe Bytes
Nothing ->
          Ptr CZooOp
-> BA# Word8
-> Ptr CChar
-> Int
-> Int
-> AclVector
-> CreateMode
-> MutableByteArray# RealWorld
-> CInt
-> IO ()
I.c_hs_zoo_create_op_init' Ptr CZooOp
op BA# Word8
path' Ptr CChar
forall a. Ptr a
nullPtr Int
0 (-Int
1) AclVector
acl CreateMode
mode MutableByteArray# RealWorld
mba# CInt
buflen'
    MutableByteArray RealWorld
mba_path <- ByteArray -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
ByteArray -> m (MutableByteArray (PrimState m))
Z.unsafeThawByteArray (ByteArray -> IO (MutableByteArray (PrimState IO)))
-> ByteArray -> IO (MutableByteArray (PrimState IO))
forall a b. (a -> b) -> a -> b
$ BA# Word8 -> ByteArray
Z.ByteArray BA# Word8
path'
    (MutableByteArray RealWorld, TouchListBytes)
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableByteArray RealWorld
mba, [MutableByteArray RealWorld
mba_path, MutableByteArray RealWorld
mba])

-- | Init delete op.
--
-- This function initializes a 'T.ZooOp' with the arguments for a ZOO_DELETE_OP.
zooDeleteOpInit
  :: CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> Maybe CInt
  -- ^ The expected version of the node. The function will fail
  -- if the actual version of the node does not match the expected version.
  -- If Nothing is used the version check will not take place.
  -> T.ZooOp
zooDeleteOpInit :: CBytes -> Maybe CInt -> ZooOp
zooDeleteOpInit CBytes
path Maybe CInt
m_version = (Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp
I.ZooDeleteOp ((Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp)
-> (Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp
forall a b. (a -> b) -> a -> b
$ \Ptr CZooOp
op -> do
  CBytes
-> (BA# Word8 -> IO ((), TouchListBytes))
-> IO ((), TouchListBytes)
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ((), TouchListBytes)) -> IO ((), TouchListBytes))
-> (BA# Word8 -> IO ((), TouchListBytes))
-> IO ((), TouchListBytes)
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
    Ptr CZooOp -> BA# Word8 -> CInt -> IO ()
I.c_zoo_delete_op_init Ptr CZooOp
op BA# Word8
path' (CInt -> Maybe CInt -> CInt
forall a. a -> Maybe a -> a
fromMaybe (-CInt
1) Maybe CInt
m_version)
    MutableByteArray RealWorld
mba_path <- ByteArray -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
ByteArray -> m (MutableByteArray (PrimState m))
Z.unsafeThawByteArray (ByteArray -> IO (MutableByteArray (PrimState IO)))
-> ByteArray -> IO (MutableByteArray (PrimState IO))
forall a b. (a -> b) -> a -> b
$ BA# Word8 -> ByteArray
Z.ByteArray BA# Word8
path'
    ((), TouchListBytes) -> IO ((), TouchListBytes)
forall (m :: * -> *) a. Monad m => a -> m a
return ((), [MutableByteArray RealWorld
mba_path])

-- | Init set op.
--
-- This function initializes an 'T.ZooOp' with the arguments for a ZOO_SETDATA_OP.
zooSetOpInit
  :: CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> Maybe Bytes
  -- ^ Data to be written to the node.
  --
  --  To set NULL as data use this parameter as Nothing.
  -> Maybe CInt
  -- ^ The expected version of the node. The function will fail
  -- if the actual version of the node does not match the expected version.
  -- If Nothing is used the version check will not take place.
  -> T.ZooOp
zooSetOpInit :: CBytes -> Maybe Bytes -> Maybe CInt -> ZooOp
zooSetOpInit CBytes
path Maybe Bytes
m_value Maybe CInt
m_version = (Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
-> ZooOp
I.ZooSetOp ((Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
 -> ZooOp)
-> (Ptr CZooOp -> IO (MutableByteArray RealWorld, TouchListBytes))
-> ZooOp
forall a b. (a -> b) -> a -> b
$ \Ptr CZooOp
op -> do
  CBytes
-> (BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> (BA# Word8 -> IO (MutableByteArray RealWorld, TouchListBytes))
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
    mba :: MutableByteArray RealWorld
mba@(Z.MutableByteArray MutableByteArray# RealWorld
mba#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
Z.newPinnedByteArray Int
I.statSize
    let version :: CInt
version = CInt -> Maybe CInt -> CInt
forall a. a -> Maybe a -> a
fromMaybe (-CInt
1) Maybe CInt
m_version
    case Maybe Bytes
m_value of
      Just Bytes
value -> Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
Z.withPrimVectorUnsafe Bytes
value ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \BA# Word8
val' Int
offset Int
len ->
        Ptr CZooOp
-> BA# Word8
-> BA# Word8
-> Int
-> Int
-> CInt
-> MutableByteArray# RealWorld
-> IO ()
I.c_hs_zoo_set_op_init Ptr CZooOp
op BA# Word8
path' BA# Word8
val' Int
offset Int
len CInt
version MutableByteArray# RealWorld
mba#
      Maybe Bytes
Nothing -> Ptr CZooOp
-> BA# Word8
-> Ptr Word8
-> Int
-> Int
-> CInt
-> MutableByteArray# RealWorld
-> IO ()
I.c_hs_zoo_set_op_init' Ptr CZooOp
op BA# Word8
path' Ptr Word8
forall a. Ptr a
nullPtr Int
0 (-Int
1) CInt
version MutableByteArray# RealWorld
mba#
    MutableByteArray RealWorld
mba_path <- ByteArray -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
ByteArray -> m (MutableByteArray (PrimState m))
Z.unsafeThawByteArray (ByteArray -> IO (MutableByteArray (PrimState IO)))
-> ByteArray -> IO (MutableByteArray (PrimState IO))
forall a b. (a -> b) -> a -> b
$ BA# Word8 -> ByteArray
Z.ByteArray BA# Word8
path'
    (MutableByteArray RealWorld, TouchListBytes)
-> IO (MutableByteArray RealWorld, TouchListBytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableByteArray RealWorld
mba, [MutableByteArray RealWorld
mba_path, MutableByteArray RealWorld
mba])

-- | Init check op.
--
-- This function initializes an 'T.ZooOp' with the arguments for a ZOO_CHECK_OP.
zooCheckOpInit
  :: CBytes
  -- ^ The name of the node. Expressed as a file name with slashes
  -- separating ancestors of the node.
  -> CInt       -- FIXME: does this can set to -1 ?
  -- ^ The expected version of the node. The function will fail
  -- if the actual version of the node does not match the expected version.
  -> T.ZooOp
zooCheckOpInit :: CBytes -> CInt -> ZooOp
zooCheckOpInit CBytes
path CInt
version = (Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp
I.ZooCheckOp ((Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp)
-> (Ptr CZooOp -> IO ((), TouchListBytes)) -> ZooOp
forall a b. (a -> b) -> a -> b
$ \Ptr CZooOp
op -> do
  CBytes
-> (BA# Word8 -> IO ((), TouchListBytes))
-> IO ((), TouchListBytes)
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
path ((BA# Word8 -> IO ((), TouchListBytes)) -> IO ((), TouchListBytes))
-> (BA# Word8 -> IO ((), TouchListBytes))
-> IO ((), TouchListBytes)
forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' -> do
    Ptr CZooOp -> BA# Word8 -> CInt -> IO ()
I.c_zoo_check_op_init Ptr CZooOp
op BA# Word8
path' CInt
version
    MutableByteArray RealWorld
mba_path <- ByteArray -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
ByteArray -> m (MutableByteArray (PrimState m))
Z.unsafeThawByteArray (ByteArray -> IO (MutableByteArray (PrimState IO)))
-> ByteArray -> IO (MutableByteArray (PrimState IO))
forall a b. (a -> b) -> a -> b
$ BA# Word8 -> ByteArray
Z.ByteArray BA# Word8
path'
    ((), TouchListBytes) -> IO ((), TouchListBytes)
forall (m :: * -> *) a. Monad m => a -> m a
return ((), [MutableByteArray RealWorld
mba_path])

-------------------------------------------------------------------------------

-- | Create a handle to used communicate with zookeeper.
--
-- This function creates a new handle and a zookeeper session that corresponds
-- to that handle. At the underlying c side, session establishment is asynchronous,
-- meaning that the session should not be considered established until (and unless)
-- an event of state ZOO_CONNECTED_STATE is received. In haskell, this will block
-- until state received.
--
-- If it fails to create a new zhandle or not connected, an exception will be
-- throwed.
zookeeperInit
  :: HasCallStack
  => CBytes
  -- ^ host, comma separated host:port pairs, each corresponding to a zk
  -- server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
  -> CInt
  -- ^ timeout
  -> Maybe T.ClientID
  -- ^ The id of a previously established session that this client will be
  -- reconnecting to. Pass 'Nothing' if not reconnecting to a previous
  -- session. Clients can access the session id of an established, valid,
  -- connection by calling 'zooGetClientID'. If the session corresponding to
  -- the specified clientid has expired, or if the clientid is invalid for
  -- any reason, the returned 'T.ZHandle' will be invalid -- the 'T.ZHandle'
  -- state will indicate the reason for failure (typically 'T.ZooExpiredSession').
  -> CInt
  -- ^ flags, reserved for future use. Should be set to zero.
  -> IO T.ZHandle
zookeeperInit :: CBytes -> CInt -> Maybe ClientID -> CInt -> IO ZHandle
zookeeperInit CBytes
host CInt
timeout Maybe ClientID
mclientid CInt
flags = do
  let clientid :: ClientID
clientid = ClientID -> Maybe ClientID -> ClientID
forall a. a -> Maybe a -> a
fromMaybe (Ptr () -> ClientID
I.ClientID Ptr ()
forall a. Ptr a
nullPtr) Maybe ClientID
mclientid
  CBytes -> (BA# Word8 -> IO ZHandle) -> IO ZHandle
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
host ((BA# Word8 -> IO ZHandle) -> IO ZHandle)
-> (BA# Word8 -> IO ZHandle) -> IO ZHandle
forall a b. (a -> b) -> a -> b
$ \BA# Word8
host' -> IO ZHandle -> IO ZHandle
forall a. IO a -> IO a
mask_ (IO ZHandle -> IO ZHandle) -> IO ZHandle -> IO ZHandle
forall a b. (a -> b) -> a -> b
$ do
    MVar ()
mvar <- IO (MVar ())
forall a. IO (MVar a)
newEmptyMVar
    StablePtr PrimMVar
sp <- MVar () -> IO (StablePtr PrimMVar)
newStablePtrPrimMVar MVar ()
mvar  -- freed by hs_try_takemvar()
    ForeignPtr HsWatcherCtx
ctx <- Int -> IO (ForeignPtr HsWatcherCtx)
forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes Int
I.hsWatcherCtxSize
    (HsWatcherCtx
ctxResult, ZHandle
zhResult) <- ForeignPtr HsWatcherCtx
-> (Ptr HsWatcherCtx -> IO (HsWatcherCtx, ZHandle))
-> IO (HsWatcherCtx, ZHandle)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr HsWatcherCtx
ctx ((Ptr HsWatcherCtx -> IO (HsWatcherCtx, ZHandle))
 -> IO (HsWatcherCtx, ZHandle))
-> (Ptr HsWatcherCtx -> IO (HsWatcherCtx, ZHandle))
-> IO (HsWatcherCtx, ZHandle)
forall a b. (a -> b) -> a -> b
$ \Ptr HsWatcherCtx
ctx' -> do
      (Int
cap, Bool
_) <- ThreadId -> IO (Int, Bool)
threadCapability (ThreadId -> IO (Int, Bool)) -> IO ThreadId -> IO (Int, Bool)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO ThreadId
myThreadId
      ZHandle
zh <- StablePtr PrimMVar
-> Int
-> Ptr HsWatcherCtx
-> BA# Word8
-> CInt
-> ClientID
-> CInt
-> IO ZHandle
I.c_hs_zookeeper_init StablePtr PrimMVar
sp Int
cap Ptr HsWatcherCtx
ctx' BA# Word8
host' CInt
timeout ClientID
clientid CInt
flags
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ZHandle
zh ZHandle -> ZHandle -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr () -> ZHandle
I.ZHandle Ptr ()
forall a. Ptr a
nullPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IO CInt
E.getCErrNum IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> CallStack -> IO ()) -> CallStack -> CInt -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip CInt -> CallStack -> IO ()
forall a. CInt -> CallStack -> IO a
E.throwZooError CallStack
HasCallStack => CallStack
callStack
      MVar () -> IO ()
forall a. MVar a -> IO a
takeMVar MVar ()
mvar IO () -> IO ThreadId -> IO ()
forall a b. IO a -> IO b -> IO a
`onException` IO () -> IO ThreadId
forkIO (do MVar () -> IO ()
forall a. MVar a -> IO a
takeMVar MVar ()
mvar; ForeignPtr HsWatcherCtx -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr HsWatcherCtx
ctx)
      HsWatcherCtx
ctxData <- Ptr HsWatcherCtx -> IO HsWatcherCtx
I.peekHsWatcherCtx Ptr HsWatcherCtx
ctx'
      (HsWatcherCtx, ZHandle) -> IO (HsWatcherCtx, ZHandle)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWatcherCtx
ctxData, ZHandle
zh)
    case HsWatcherCtx -> ZooState
I.watcherCtxState HsWatcherCtx
ctxResult of
      ZooState
I.ZooConnectedState -> ZHandle -> IO ZHandle
forall (m :: * -> *) a. Monad m => a -> m a
return ZHandle
zhResult
      ZooState
state -> ZINVALIDSTATE -> IO ZHandle
forall e a. Exception e => e -> IO a
E.throwIO (ZINVALIDSTATE -> IO ZHandle) -> ZINVALIDSTATE -> IO ZHandle
forall a b. (a -> b) -> a -> b
$ ZooExInfo -> ZINVALIDSTATE
E.ZINVALIDSTATE (ZooExInfo -> ZINVALIDSTATE) -> ZooExInfo -> ZINVALIDSTATE
forall a b. (a -> b) -> a -> b
$ Text -> CallStack -> ZooExInfo
E.ZooExInfo (ZooState -> Text
forall a. Print a => a -> Text
Text.toText ZooState
state) CallStack
HasCallStack => CallStack
callStack

{-# INLINABLE zookeeperClose #-}
zookeeperClose :: T.ZHandle -> IO ()
zookeeperClose :: ZHandle -> IO ()
zookeeperClose = IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> (CInt -> IO CInt) -> CInt -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => CInt -> IO CInt
CInt -> IO CInt
E.throwZooErrorIfNotOK (CInt -> IO ()) -> (ZHandle -> IO CInt) -> ZHandle -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ZHandle -> IO CInt
I.c_zookeeper_close_safe

-- | Return the client session id, only valid if the connections
-- is currently connected (ie. last watcher state is 'T.ZooConnectedState')
zooClientID :: T.ZHandle -> IO T.ClientID
zooClientID :: ZHandle -> IO ClientID
zooClientID = ZHandle -> IO ClientID
I.c_zoo_client_id

-- | Checks if the current zookeeper connection state can't be recovered.
--
-- If True, the application must close the zhandle and then try to reconnect.
isUnrecoverable
  :: T.ZHandle
  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
  -> IO Bool
  -- ^ Return True if connection is unrecoverable
isUnrecoverable :: ZHandle -> IO Bool
isUnrecoverable ZHandle
zh = (CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
0) (CInt -> Bool) -> IO CInt -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ZHandle -> IO CInt
I.c_is_unrecoverable ZHandle
zh

-- | Get the state of the zookeeper connection
--
-- The return valud will be one of the State Consts
zooState :: T.ZHandle -> IO T.ZooState
zooState :: ZHandle -> IO ZooState
zooState = ZHandle -> IO ZooState
I.c_zoo_state

-- | Return the timeout for this session, only valid if the connections
-- is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This
-- value may change after a server re-connect.
zooRecvTimeout :: T.ZHandle -> IO CInt
zooRecvTimeout :: ZHandle -> IO CInt
zooRecvTimeout = ZHandle -> IO CInt
I.c_zoo_recv_timeout