-- 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. The library may use TLS for secure connections to -- brokers that provide security over TLS. -- -- 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.5.0 -- | Exceptions for the Stompl Client. Note that exceptions thrown in -- internal worker threads (sender and listener) will be forwarded to the -- connection owner, that is the thread that actually initialised the -- connection. Since, in some circumstances, several exceptions may be -- thrown in response to one error event (e.g. the broker sends an -- error frame and, immediately afterwards, closes the connection), the -- connection owner should implement a robust exception handling -- mechanism. module Network.Mom.Stompl.Client.Exception data StomplException -- | Currently not used SocketException :: String -> StomplException -- | Thrown when a worker thread terminates unexpectedly; usually, this is -- a consequence of another error (e.g. the broker closed the -- socket) and you will probably receive another exception (e.g. a -- BrokerException) WorkerException :: 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 closed 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 GHC.Classes.Eq Network.Mom.Stompl.Client.Exception.StomplException instance GHC.Read.Read Network.Mom.Stompl.Client.Exception.StomplException instance GHC.Show.Show Network.Mom.Stompl.Client.Exception.StomplException instance GHC.Exception.Type.Exception Network.Mom.Stompl.Client.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 lifetime 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. -- -- Since Connection is a heavy data type, you should try to reduce -- the number of connections to the same broker within the same process - -- there is ideally only one connection per broker in one process. -- -- 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 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. withConnection :: String -> Int -> [Copt] -> [Header] -> (Con -> IO a) -> IO a -- | 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 -- | Wait n milliseconds after the connection has been closed by the -- broker to give the library some time to process the error message (if -- one has been sent). OWaitError :: Int -> Copt -- | The maximum size of TCP/IP packets. This option is currently ignored. -- Instead, Network defines the packet size (currently hard-wired -- 4KB). The maximum message size is 1024 times this value, i.e. -- 4MB. OMaxRecv :: Int -> Copt -- | This option defines the client's bid for negotiating heartbeats -- providing an accepted lower and upper bound expessed as milliseconds -- between heartbeats. By default, no heart beats are sent or accepted OHeartBeat :: Heart -> Copt -- | Authentication: user and password OAuth :: String -> String -> Copt -- | Identification: specifies the JMS Client ID for persistent connections OClientId :: String -> Copt -- | With this option set, "connect" will use a STOMP frame instead -- of a CONNECT frame OStomp :: Copt -- | Connection timeout in milliseconds; if the broker does not respond to -- a connect request within this time frame, a ConnectException is -- thrown. If the value is <= 0, the program will wait forever. OTmo :: Int -> Copt -- | TLSClientConfig (see TLS for details) for TLS -- connections. If the option is not given, a plain TCP/IP connection is -- used. OTLS :: TLSClientConfig -> Copt -- | Action to handle Error frames; if the option is not given, an -- exception is raised on arrival of an error frame. If it is given, one -- should also pass a value for OWaitError to give the error handler time -- to execute. OEH :: EHandler -> Copt -- | Action executed when an Error Frame is received; the typical use case -- is logging the text of the Error Frame. type EHandler = Con -> Frame -> IO () -- | A Queue for receiving messages data Reader a -- | A Queue for sending messages. data Writer a -- | Creates a Reader with the lifetime 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 -- ...
--   
-- -- A newReader stores data in the connection c. If the lifetime of -- a reader is shorter than that of its connection it should call -- destroyReader to avoid memory leaks. In such cases, it is -- usually preferable to use withReader. newReader :: Con -> String -> String -> [Qopt] -> [Header] -> InBound a -> IO (Reader a) -- | Removes all references to the reader from the connection. destroyReader :: Reader a -> IO () -- | Creates a Writer with the lifetime 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
--   
-- -- Currently no references to the writer are stored in the connection. It -- is advisable, however, to use withWriter instead of -- newWriter whenever the lifetime of a writer is shorter than -- that of the connection. In cases where this is not possible, you -- should use destroyWriter when the writer is not needed anymore. -- Currently destroyWriter does nothing, but this may change in -- the future. newWriter :: Con -> String -> String -> [Qopt] -> [Header] -> OutBound a -> IO (Writer a) -- | Does nothing, but should be used with newWriter. destroyWriter :: Writer a -> IO () -- | Creates a Reader with limited lifetime. The queue will live -- only in the scope of the action that is passed as last parameter. The -- function is useful for readers with a lifetime shorter than that of -- the connection. 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 lifetime -- 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 i -> (Reader i -> IO r) -> IO r -- | Creates a Writer with limited lifetime. The queue will live -- only in the scope of the action that is passed as last parameter. The -- function should be used for writers with a lifetime shorter than that -- of the connection. -- -- withWriter returns the result of the action. Since the lifetime -- of the queue is limited to the action, it should not be returned. Any -- operation on a writer created by withWriter outside the action -- will raise a QueueException. withWriter :: Con -> String -> String -> [Qopt] -> [Header] -> OutBound o -> (Writer o -> IO r) -> IO r -- | Creates a pair of (Reader i, Writer o) with limited -- lifetime. The pair will live only in the scope of the action that is -- passed as last parameter. The function is useful for readers/writers -- used in combination, e.g. to emulate a client/server kind of -- communication. -- -- withPair returns the result of the action passed in. -- -- The parameters are: -- -- -- -- The reason for introducing the reader and writer description is to -- provide error detection at compile time: It is this way much more -- difficult to accidently confuse the writer's and the reader's -- parameters (e.g. passing the writer's Qopts to the -- reader). withPair :: Con -> String -> ReaderDesc i -> WriterDesc o -> ((Reader i, Writer o) -> IO r) -> IO r -- | The Reader parameters of withPair: -- -- type ReaderDesc i = (String, [Qopt], [Header], InBound i) -- | The Writer parameters of withPair -- -- type WriterDesc o = (String, [Qopt], [Header], OutBound o) -- | 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 is usually not -- visible to applications, but may be made visible in the case of -- sending messages using writeQWith. writeQWith return the -- receipt identifier and the application can later invoke -- waitReceipt to explicitly wait for the broker confirming this -- receipt. -- -- 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 - and check for the confirmation of the -- receipt only later. 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 -- request a receipt with a message 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, i.e. 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. Furthermore, if OMode is -- either Client or ClientIndi, then this option forces -- readQ to send an acknowledgement 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 -- | Do not automatically add a content-length header ONoContentLen :: 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: -- -- -- -- A simple in-bound converter for plain strings is for instance: -- --
--   let iconv _ _ _ = return . unpack
--   
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 . pack
--   
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 too 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 -- | This is a variant of writeQ that overwrites the destination -- queue defined in the writer queue. It can be used for ad hoc -- communication and for emulations of client/server-like protocols: the -- client would pass the name of the queue where it expects the server -- response in a header; the server would send the reply to the queue -- indicated in the header using writeAdHoc. The additional -- String parameter contains the destination. writeAdHoc :: Writer a -> String -> Type -> [Header] -> a -> IO () -- | This is a variant of writeAdHoc 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. Please refer to -- writeQWith for more details. writeAdHocWith :: Writer a -> String -> 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_ <- timeout tmo $ waitReceipt c r
--   case mb_ of
--    Nothing -> -- error handling
--    Just _  -> do -- ...
--   
waitReceipt :: Con -> Receipt -> IO () data Tx -- | 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 has been 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 but the one that -- has actually 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] -> (Tx -> IO a) -> IO a -- | 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 option without OTimeout, since, in all -- probability, there will be receipts that have 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 GHC.Classes.Eq Network.Mom.Stompl.Client.Queue.Qopt instance GHC.Read.Read Network.Mom.Stompl.Client.Queue.Qopt instance GHC.Show.Show Network.Mom.Stompl.Client.Queue.Qopt instance GHC.Classes.Eq (Network.Mom.Stompl.Client.Queue.Writer a) instance GHC.Classes.Eq (Network.Mom.Stompl.Client.Queue.Reader a)