-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Stompl Client Library -- -- The Stomp Protocol specifies message-oriented interoperability. -- Applications connect to a message broker to send (publish) or receive -- (subscribe) messages through queues. Interoperating applications do -- not know the location or internal structure of each other. They see -- only each other's interfaces, i.e. the messages published and -- subscribed through the broker. The Stomp Queue library provides a -- Stomp client, using abstractions like Connection, -- Transaction, Queue and Message. More information, -- examples and a test suite are available on -- http://github.com/toschoo/mom. The Stomp specification can be -- found at http://stomp.github.com. @package stomp-queue @version 0.0.3 -- | Exceptions for the Stompl Client module Network.Mom.Stompl.Client.Exception -- | The Stompl Client uses exceptions to communicate errors to the user -- application. data StomplException -- | Thrown on problems with the socket, e.g. when a message cannot -- be sent SocketException :: String -> StomplException -- | Thrown when something against the protocol happens, e.g. an -- unexpected frame is received or a message from a queue that was not -- subscribed ProtocolException :: String -> StomplException -- | Thrown on wrong uses of queues, e.g. use of a queue outside its -- scope QueueException :: String -> StomplException -- | Thrown on transaction errors, e.g. pending acks TxException :: String -> StomplException -- | Thrown on connection errors, e.g. connection was disconnected ConnectException :: String -> StomplException -- | Should be thrown by user-defined converters ConvertException :: String -> StomplException -- | Thrown when an error frame is received BrokerException :: String -> StomplException -- | Thrown by abort AppException :: String -> StomplException -- | You hit a bug! This exception is only thrown when something really -- strange happened OuchException :: String -> StomplException -- | Catches any StomplException, including asynchronous exceptions -- coming from internal threads try :: IO a -> IO (Either StomplException a) -- | Throws ConvertException to signal a conversion error. convertError :: String -> IO a instance Typeable StomplException instance Show StomplException instance Read StomplException instance Eq StomplException instance Exception StomplException -- | The Stomp Protocol specifies message-oriented interoperability. -- Applications connect to a message broker to send (publish) or receive -- (subscribe) messages through queues. Interoperating applications do -- not know the location or internal structure of each other. They only -- see interfaces, i.e. the messages published and subscribed -- through the broker. -- -- The Stompl Client library implements a Stomp client using abstractions -- like Connection, Transaction and queues in terms of -- Reader and Writer. module Network.Mom.Stompl.Client.Queue -- | Initialises a connection and executes an IO action. The -- connection life time is the scope of this action. The connection -- handle, Con, that is passed to the action should not be -- returned from withConnection. Connections, however, can be -- shared among threads. In this case, the programmer has to take care -- not to terminate the action before all other threads working on the -- connection have finished. -- -- Paramter: -- -- -- -- withConnection returns the result of the action passed into it. -- -- withConnection will always disconnect from the broker when the -- action has terminated, even if an exception is raised. -- -- Example: -- --
--   withConnection "localhost" 61613 [] $ \c -> do
--   
-- -- This would connect to a broker listening to the loopback interface, -- port number 61613. The action is defined after the hanging do. -- -- Internally, connections use concurrent threads; errors are -- communicated by throwing exceptions to the owner of the connection, -- where the owner is the thread that created the connection by calling -- withConnection. It is therefore advisable to start different -- connections in different threads, so that each thread will receive -- only exceptions related to the connection it has opened. -- -- Example: -- --
--   t <- forkIO $ withConnection_ "127.0.0.1" 61613 [] $ \c -> do
--   
withConnection :: String -> Int -> [Copt] -> (Con -> IO a) -> IO a -- | A variant of withConnection that returns nothing withConnection_ :: String -> Int -> [Copt] -> (Con -> IO ()) -> IO () -- | Opaque Connection handle. Only valid within the action passed to -- withConnection. data Con -- | Heart-beat configuration; the first Int of the pair represents -- the frequency in which the sender wants to send heart-beats; the -- second represents the highest frequency in which the sender can accept -- heart-beats. The frequency is expressed as the period in milliseconds -- between two heart-beats. For details on negotiating heart-beats, -- please refer to the Stomp specification. type Heart = (Int, Int) -- | Options passed to a connection data Copt -- | Tells the connection to wait n milliseconds for the -- Receipt sent with Disconnect at the end of the session. -- The Stomp protocol advises to request a receipt and to wait for -- it before actually closing the socket. Many brokers, however, do not -- implement this feature (or implement it inappropriately, closing the -- connection immediately after having sent the receipt). -- withConnection, for this reason, ignores the receipt by -- default and simply closes the socket after having sent the -- Disconnect frame. If your broker shows a correct behaviour, it -- is advisable to use this option. OWaitBroker :: Int -> Copt -- | The maximum size of TCP/IP packets. Indirectly, this options also -- defines the maximum message size which is 10 * maxReceive. By -- default, the maximum packet size is 1024 bytes. OMaxRecv :: Int -> Copt -- | This option defines the client's bid for negotiating heart beats (see -- HeartBeat). By default, no heart beats are sent or accepted OHeartBeat :: (Heart) -> Copt -- | Authentication: user and password OAuth :: String -> String -> Copt -- | A Queue for receiving messages data Reader a -- | A Queue for sending messages. data Writer a -- | Creates a Reader with the life time of the connection -- Con. Creating a receiving queue involves interaction with the -- broker; this may result in preempting the calling thread, depending on -- the options [Qopt]. -- -- Parameters: -- -- -- -- A usage example to create a Reader with Connection -- c and the in-bound converter iconv would be: -- --
--   q <- newReader c "TestQ" "/queue/test" [] [] iconv
--   
-- -- A call to newReader may result in preemption when one of the -- options OWaitReceipt or OWithReceipt are given; an -- example for such a call with tmo an Int value -- representing a timeout in microseconds and the result -- mbQ of type Maybe is: -- --
--   mbQ <- timeout tmo $ newReader c "TestQ" "/queue/test" [OWaitReceipt] [] oconv
--   case mbQ of
--     Nothing -> -- handle error
--     Just q  -> do -- ...
--   
newReader :: Con -> String -> String -> [Qopt] -> [Header] -> InBound a -> IO (Reader a) -- | Creates a Writer with the life time of the connection -- Con. Creating a sending queue does not involve interaction with -- the broker and will not preempt the calling thread. -- -- A sending queue may be created like in the following code fragment, -- where oconv is an already defined out-bound converter: -- --
--   q <- newWriter c "TestQ" "/queue/test" [] [] oconv
--   
newWriter :: Con -> String -> String -> [Qopt] -> [Header] -> OutBound a -> IO (Writer a) -- | Creates a Reader with limited life time. The queue will live -- only in the scope of the action that is passed as last parameter. The -- function is useful for readers that are used only temporarly, -- e.g. during initialisation. When the action terminates, the -- client unsubscribes from the broker queue - even if an exception is -- raised. -- -- withReader returns the result of the action. Since the life -- time of the queue is limited to the action, it should not be returned. -- Any operation on a reader created by withReader outside the -- action will raise QueueException. -- -- A usage example is: -- --
--   x <- withReader c "TestQ" "/queue/test" [] [] iconv $ \q -> do
--   
withReader :: Con -> String -> String -> [Qopt] -> [Header] -> InBound a -> (Reader a -> IO b) -> IO b -- | A variant of withReader for actions that do not return -- anything. withReader_ :: Con -> String -> String -> [Qopt] -> [Header] -> InBound a -> (Reader a -> IO ()) -> IO () -- | Options that may be passed to newReader and newWriter -- and their variants. data Qopt -- | A queue created with OWithReceipt will request a receipt on all -- interactions with the broker. The handling of receipts may be -- transparent to applications or may be made visible by using -- writeQWith. Note that the option has effect right from the -- beginning, i.e. a Reader created with -- OWithReceipt will issue a request for receipt when subscribing -- to a Stomp queue. OWithReceipt :: Qopt -- | A queue created with OWaitReceipt will wait for the receipt -- before returning from a call that has issued a request for receipt. -- This implies that the current thread will yield the processor. -- writeQ will internally create a request for receipt and wait -- for the broker to confirm the receipt before returning. Note that, for -- newReader, there is no difference between OWaitReceipt -- and OWithReceipt. Either option will cause the thread to -- preempt until the receipt is confirmed. -- -- On writing a message, this is not always the preferred method. You may -- want to fire and forget - for a while, before you check that your -- message has actually been handled by the broker. In this case, you -- will create the Writer with OWithReceipt only and, -- later, after having sent a message with writeQWith, wait for -- the receipt using waitReceipt. Note that OWaitReceipt -- without OWithReceipt has no meaning with writeQ and -- writeQWith. If you want to send a receipt and wait for the -- broker to confirm it, you have to use both options. -- -- It is good practice to use timeout with all calls that may wait -- for receipts, ie newReader and withReader with -- options OWithReceipt or OWaitReceipt, or writeQ -- and writeQWith with options OWaitReceipt, or -- ackWith and nackWith. OWaitReceipt :: Qopt -- | The option defines the AckMode of the queue, which is relevant -- for Reader only. AckMode is one of: Auto, -- Client, ClientIndi. -- -- If OMode is not given, Auto is assumed as default. -- -- For more details, see AckMode. OMode :: AckMode -> Qopt -- | Expression often used by René Artois. What he tries to say is: If -- OMode is either Client or ClientIndi, send an -- acknowledgment automatically when a message has been read from the -- queue. OAck :: Qopt -- | A queue created with OForceTx will throw QueueException -- when used outside a Transaction. OForceTx :: Qopt data AckMode :: * -- | A successfully sent message is automatically considered ack'd Auto :: AckMode -- | The client is expected to explicitly confirm the receipt of a message -- by sending an Ack frame; all message older than the ack'd -- message since the last Ack (or the beginning of the session) -- are implicitly ack'd as well. This is called cumulative ack. Client :: AckMode -- | Non-cumulative ack: The client is expected to explicitly confirm the -- receipt of a message by sending an Ack frame; only the message -- with the msg-id in the Ack frame is actually ack'd ClientIndi :: AckMode -- | Converters are user-defined actions passed to newReader -- (InBound) and newWriter (OutBound) that convert a -- ByteString to a value of type a (InBound) or a -- value of type a to ByteString (OutBound). -- Converters are, hence, similar to put and get in the -- Binary monad. -- -- The reason for using explicit, user-defined converters instead of -- Binary encode and decode is that the conversion -- with queues may be much more complex, involving reading configurations -- or other IO actions. Furthermore, we have to distinguish -- between data types and there binary encoding when sent over the -- network. This distinction is made by MIME types. Two -- applications may send the same data type, but one encodes this type as -- "text/plain", the other as "text/xml". InBound conversions have -- to consider the MIME type and, hence, need more input -- parameters than provided by decode. encode and -- decode, however, can be used internally by user-defined -- converters. -- -- The parameters expected by an InBound converter are: -- -- -- -- The simplest possible in-bound converter for plain strings may be -- created like this: -- --
--   let iconv _ _ _ = return . toString
--   
type InBound a = Type -> Int -> [Header] -> ByteString -> IO a -- | Out-bound converters are much simpler. Since the application developer -- knows, which encoding to use, the MIME type is not needed. The -- converter receives only the value of type a and converts it -- into a ByteString. A simple example to create an out-bound -- converter for plain strings could be: -- --
--   let oconv = return . fromString
--   
type OutBound a = a -> IO ByteString -- | Removes the oldest message from the queue and returns it as -- Message. The message cannot be read from the queue by another -- call to readQ within the same connection. Wether other -- connections will receive the message as well depends on the broker and -- the queue patterns it implements. If the queue is currently empty, the -- thread will preempt until a message arrives. -- -- If the queue was created with OMode other than Auto and -- with OAck, then an ack will be automatically sent to the -- broker; if OAck was not set, the message will be registered as -- pending ack. -- -- Note that, when readQ sends an ack internally, it will -- not request a receipt from the broker. The rationale for this design -- is simplicity. If the function expected a receipt, it would have to -- either wait for the receipt or return it. In the first case, it would -- be difficult for the programmer to distinguish, on a timeout, between -- no message available and no receipt arrived. In the -- second case, the receipt would need to be returned. This would -- unnecessarily blow up the interface. If you need the reliability of -- receipts, you should create the queue without OAck and use -- ackWith to acknowledge the message explicitly. readQ :: Reader a -> IO (Message a) -- | Adds the value a as message at the end of the queue. The Mime -- type as well as the headers are added to the message. -- -- If the queue was created with the option OWithReceipt, -- writeQ will request a receipt from the broker. If the queue was -- additionally created with OWaitReceipt, writeQ will -- preempt until the receipt is confirmed. -- -- The Stomp headers are useful for brokers that provide selectors on -- subscribe, see newReader for details. -- -- A usage example for a Writer q of type String may -- be (nullType is defined as text/plain in -- Codec.MIME): -- --
--   writeQ q nullType [] "hello world!"
--   
-- -- For a Writer that was created with OWithReceipt and -- OWaitReceipt, the function should be called with -- timeout: -- --
--   mbR <- timeout tmo $ writeQ q nullType [] "hello world!"
--   case mbR of
--     Nothing -> -- error handling
--     Just r  -> do -- ...
--   
writeQ :: Writer a -> Type -> [Header] -> a -> IO () -- | This is a variant of writeQ that is particularly useful for -- queues created with OWithReceipt, but without -- OWaitReceipt. It returns the Receipt, so that it can be -- waited for later, using waitReceipt. -- -- Note that the behaviour of writeQWith, besides of returning the -- receipt, is the same as writeQ, i.e., on a queue with -- OWithReceipt and OWaitReceipt writeQWith will -- wait for the receipt being confirmed. In this case, the returned -- receipt is, in fact, of no further use for the application. -- -- The function is used like: -- --
--   r <- writeQWith q nullType [] "hello world!"
--   
writeQWith :: Writer a -> Type -> [Header] -> a -> IO Receipt -- | Any content received from a queue is wrapped in a message. It is, in -- particular, the return value of readQ. data Message a -- | Returns the content of the message in the format produced by an -- in-bound converter msgContent :: Message a -> a -- | The encoded content msgRaw :: Message a -> ByteString -- | The MIME type of the content msgType :: Message a -> Type -- | The length of the encoded content msgLen :: Message a -> Int -- | The Stomp headers that came with the message msgHdrs :: Message a -> [Header] -- | This is a receipt. data Rec -- | A valid receipt Rec :: Int -> Rec -- | No receipt was sent with this interaction. Receiving a NoRec is -- not an error, but the result of an inconsistent - but harmless - use -- of writeQWith on a queue that does not send receipts. An -- application should, of course, not try to wait for a NoRec. It -- will never be confirmed. NoRec :: Rec -- | Just a nicer word for Rec type Receipt = Rec -- | Waits for the Receipt to be confirmed by the broker. Since the -- thread will preempt, the call should be protected with timeout, -- e.g.: -- --
--   mb_ <- waitReceipt c r
--   case mb_ of
--    Nothing -> -- error handling
--    Just _  -> do -- ...
--   
waitReceipt :: Con -> Receipt -> IO () -- | Starts a transaction and executes the action in the last parameter. -- After the action has finished, the transaction will be either -- committed or aborted even if an exception was raised. Note that, -- depending on the options, the way a transaction is terminated may -- vary, refer to Topt for details. -- -- Transactions cannot be shared among threads. Transactions are -- internally protected against access from any thread that has not -- started the transaction. -- -- It is not advisable to use withTransaction with -- timeout. It is preferred to use timeout on the the -- actions executed within this transaction. Whether and how much time -- the transaction itself shall wait for the completion of on-going -- interactions with the broker, in particular pending receipts, shall be -- controlled by the OTimeout option. -- -- withTransaction returns the result of the action. -- -- The simplest usage example with a Connection c is: -- --
--   r <- withTransaction c [] $ \_ -> do
--   
-- -- If the transaction shall use receipts and, before terminating, wait -- 100ms for all receipts to be confirmed by the broker -- withTransaction is called like: -- --
--   eiR <- try $ withTransaction c [OTimeout 100, OWithReceipts] \_ -> do
--   case eiR of
--     Left e  -> -- error handling
--     Right x -> do -- ..
--   
-- -- Note that try is used to catch any StomplException. withTransaction :: Con -> [Topt] -> (Con -> IO a) -> IO a -- | Variant of withTransaction that does not return anything. withTransaction_ :: Con -> [Topt] -> (Con -> IO ()) -> IO () -- | Options passed to a transaction. data Topt -- | The timeout in milliseconds (not microseconds!) to wait for pending -- receipts. If receipts are pending, when the transaction is ready -- to terminate, and no timeout or a timeout <= 0 is given, and -- the option OWithReceipts was passed to -- withTransaction, the transaction will be aborted with -- TxException; otherwise it will wait until all pending -- ineractions with the broker have terminated or the timeout has expired -- - whatever comes first. If the timeout expires first, -- TxException is raised. OTimeout :: Int -> Topt -- | This option has two effects: 1) Internal interactions of the -- transaction with the broker will request receipts; 2) before ending -- the transaction, the library will check for receipts that have not yet -- been confirmed by the broker (including receipts requested by user -- calls such as writeQ or ackWith). -- -- If receipts are pending, when the transaction is ready to terminate -- and OTimeout with a value > 0 is given, the -- transaction will wait for pending receipts; otherwise the transaction -- will be aborted with TxException. Note that it, usually, does -- not make sense to use this options without OTimeout, since it -- is in all probability that a receipt has not yet been confirmed when -- the transaction terminates. OWithReceipts :: Topt -- | If a message has been received from a queue with OMode option -- other than Auto and this message has not yet been acknowledged -- when the transaction is ready to terminate, the ack is -- missing. With this option, the transaction will not commit with -- missing acks, but abort and raise TxException. OAbortMissingAcks :: Topt -- | Aborts the transaction immediately by raising AppException. The -- string passed in to abort will be added to the exception -- message. abort :: String -> IO () -- | Acknowledges the arrival of Message to the broker. It is used -- with a Connection c and a Message x like: -- --
--   ack c x
--   
ack :: Con -> Message a -> IO () -- | Acknowledges the arrival of Message to the broker, requests a -- receipt and waits until it is confirmed. Since it preempts the calling -- thread, it is usually used with timeout, for a -- Connection c, a Message x and a -- timeout in microseconds tmo like: -- --
--   mbR <- timeout tmo $ ackWith c x   
--   case mbR of
--     Nothing -> -- error handling
--     Just _  -> do -- ...
--   
ackWith :: Con -> Message a -> IO () -- | Negatively acknowledges the arrival of Message to the broker. -- For more details see ack. nack :: Con -> Message a -> IO () -- | Negatively acknowledges the arrival of Message to the broker, -- requests a receipt and waits until it is confirmed. For more details -- see ackWith. nackWith :: Con -> Message a -> IO () instance Show Qopt instance Read Qopt instance Eq Qopt instance Eq (Writer a) instance Eq (Reader a)