| Safe Haskell | None |
|---|
Ganeti.UDSServer
Description
Implementation of the Ganeti Unix Domain Socket JSON server interface.
Synopsis
- withTimeout :: Int -> String -> IO a -> IO a
- data RecvResult
- = RecvConnClosed
- | RecvError String
- | RecvOk String
- eOM :: Word8
- bEOM :: ByteString
- data MsgKeys
- strOfKey :: MsgKeys -> String
- data ServerConfig = ServerConfig {}
- data ConnectConfig = ConnectConfig {}
- data Client = Client {
- rsocket :: Handle
- wsocket :: Handle
- rbuf :: IORef ByteString
- clientConfig :: ConnectConfig
- data Server = Server {
- sSocket :: Socket
- sPath :: FilePath
- serverConfig :: ConnectConfig
- openClientSocket :: Int -> FilePath -> IO Handle
- closeClientSocket :: Handle -> IO ()
- openServerSocket :: FilePath -> IO Socket
- closeServerSocket :: Socket -> FilePath -> IO ()
- acceptSocket :: Socket -> IO Handle
- connectClient :: ConnectConfig -> Int -> FilePath -> IO Client
- connectServer :: ServerConfig -> Bool -> FilePath -> IO Server
- pipeClient :: ConnectConfig -> IO (Client, Client)
- closeServer :: MonadBase IO m => Server -> m ()
- acceptClient :: Server -> IO Client
- closeClient :: Client -> IO ()
- clientToFd :: Client -> IO (Fd, Fd)
- clientToHandle :: Client -> (Handle, Handle)
- sendMsg :: Client -> String -> IO ()
- recvUpdate :: ConnectConfig -> Handle -> ByteString -> IO (ByteString, ByteString)
- recvMsg :: Client -> IO String
- recvMsgExt :: Client -> IO RecvResult
- buildCall :: (JSON mth, JSON args) => mth -> args -> String
- parseCall :: (JSON mth, JSON args) => String -> Result (mth, args)
- buildResponse :: Bool -> JSValue -> String
- decodeError :: JSValue -> ErrorResult JSValue
- parseResponse :: String -> ErrorResult JSValue
- logMsg :: (Show e, JSON e, MonadLog m) => Handler i m o -> i -> GenericResult e JSValue -> m ()
- prepareMsg :: JSON e => GenericResult e JSValue -> (Bool, JSValue)
- type HandlerResult m o = m (Bool, GenericResult GanetiException o)
- data Handler i m o = Handler {
- hParse :: JSValue -> JSValue -> Result i
- hInputLogShort :: i -> String
- hInputLogLong :: i -> String
- hExec :: i -> HandlerResult m o
- handleJsonMessage :: (JSON o, Monad m) => Handler i m o -> i -> HandlerResult m JSValue
- handleRawMessage :: (JSON o, MonadLog m) => Handler i m o -> String -> m (Bool, String)
- isRisky :: RecvResult -> Bool
- handleClient :: (JSON o, MonadBase IO m, MonadLog m) => Handler i m o -> Client -> m Bool
- clientLoop :: (JSON o, MonadBase IO m, MonadLog m) => Handler i m o -> Client -> m ()
- listener :: (JSON o, MonadBaseControl IO m, MonadLog m) => Handler i m o -> Server -> m ()
Utility functions
withTimeout :: Int -> String -> IO a -> IO a Source #
Wrapper over System.Timeout.timeout that fails in the IO monad.
Generic protocol functionality
data RecvResult Source #
Result of receiving a message from the socket.
Constructors
| RecvConnClosed | Connection closed |
| RecvError String | Any other error |
| RecvOk String | Successfull receive |
Instances
| Eq RecvResult # | |
Defined in Ganeti.UDSServer | |
| Show RecvResult # | |
Defined in Ganeti.UDSServer Methods showsPrec :: Int -> RecvResult -> ShowS show :: RecvResult -> String showList :: [RecvResult] -> ShowS | |
Valid keys in the requests and responses.
data ServerConfig Source #
Constructors
| ServerConfig | |
Fields | |
data ConnectConfig Source #
Constructors
| ConnectConfig | |
A client encapsulation. Note that it has separate read and write handle. For sockets it is the same handle. It is required for bi-directional inter-process pipes though.
Constructors
| Client | |
Fields
| |
A server encapsulation.
Constructors
| Server | |
Fields
| |
Unix sockets
Arguments
| :: Int | connection timeout |
| -> FilePath | socket path |
| -> IO Handle |
Creates a Unix socket and connects it to the specified path,
where timeout specifies the connection timeout.
closeClientSocket :: Handle -> IO () Source #
Closes the handle. Performing the operation on a handle that has already been closed has no effect; doing so is not an error. All other operations on a closed handle will fail.
openServerSocket :: FilePath -> IO Socket Source #
Creates a Unix socket and binds it to the specified path.
closeServerSocket :: Socket -> FilePath -> IO () Source #
acceptSocket :: Socket -> IO Handle Source #
Client and server
Arguments
| :: ConnectConfig | configuration for the client |
| -> Int | connection timeout |
| -> FilePath | socket path |
| -> IO Client |
Connects to the master daemon and returns a Client.
connectServer :: ServerConfig -> Bool -> FilePath -> IO Server Source #
Creates and returns a server endpoint.
pipeClient :: ConnectConfig -> IO (Client, Client) Source #
Creates a new bi-directional client pipe. The two returned clients talk to each other through the pipe.
closeServer :: MonadBase IO m => Server -> m () Source #
Closes a server endpoint.
acceptClient :: Server -> IO Client Source #
Accepts a client
closeClient :: Client -> IO () Source #
Closes the client socket. Performing the operation on a client that has already been closed has no effect; doing so is not an error. All other operations on a closed client will fail with an exception.
clientToFd :: Client -> IO (Fd, Fd) Source #
Extracts the read (the first) and the write (the second) file descriptor
of a client. This closes the underlying Handles, therefore the original
client is closed and unusable after the call.
The purpose of this function is to keep the communication channel open,
while replacing a Client with some other means.
clientToHandle :: Client -> (Handle, Handle) Source #
Extracts the read (first) and the write (second) handles of a client. The purpose of this function is to allow using a client's handles as input/output streams elsewhere.
recvUpdate :: ConnectConfig -> Handle -> ByteString -> IO (ByteString, ByteString) Source #
Given a current buffer and the handle, it will read from the network until we get a full message, and it will return that message and the leftover buffer contents.
recvMsgExt :: Client -> IO RecvResult Source #
Extended wrapper over recvMsg.
Arguments
| :: (JSON mth, JSON args) | |
| => mth | The method |
| -> args | The arguments |
| -> String | The serialized form |
Serialize a request to String.
parseCall :: (JSON mth, JSON args) => String -> Result (mth, args) Source #
Parse the required keys out of a call.
Arguments
| :: Bool | Success |
| -> JSValue | The arguments |
| -> String | The serialized form |
Serialize the response to String.
decodeError :: JSValue -> ErrorResult JSValue Source #
Try to decode an error from the server response. This function will always fail, since it's called only on the error path (when status is False).
parseResponse :: String -> ErrorResult JSValue Source #
Check that luxi responses contain the required keys and that the call was successful.
Arguments
| :: (Show e, JSON e, MonadLog m) | |
| => Handler i m o | |
| -> i | the received request (used for logging) |
| -> GenericResult e JSValue | A message to be sent |
| -> m () |
Logs an outgoing message.
Arguments
| :: JSON e | |
| => GenericResult e JSValue | A message to be sent |
| -> (Bool, JSValue) |
Prepares an outgoing message.
Processing client requests
type HandlerResult m o = m (Bool, GenericResult GanetiException o) Source #
Constructors
| Handler | |
Fields
| |
Arguments
| :: (JSON o, Monad m) | |
| => Handler i m o | handler |
| -> i | parsed input |
| -> HandlerResult m JSValue |
Arguments
| :: (JSON o, MonadLog m) | |
| => Handler i m o | handler |
| -> String | raw unparsed input |
| -> m (Bool, String) |
Takes a request as a String, parses it, passes it to a handler and
formats its response.
isRisky :: RecvResult -> Bool Source #
handleClient :: (JSON o, MonadBase IO m, MonadLog m) => Handler i m o -> Client -> m Bool Source #
Reads a request, passes it to a handler and sends a response back to the client.
clientLoop :: (JSON o, MonadBase IO m, MonadLog m) => Handler i m o -> Client -> m () Source #
Main client loop: runs one loop of handleClient, and if that
doesn't report a finished (closed) connection, restarts itself.