1 {-# LANGUAGE OverloadedStrings #-}
3 -- generic AMQP rpc client
4 import Control.Concurrent
5 import qualified Control.Exception as X
7 import qualified Data.ByteString.Lazy.Char8 as BL
8 import qualified Data.Text as T
10 import Data.Time.Clock.POSIX
11 import Data.Version (showVersion)
13 import Network.AMQP.Utils.Connection
14 import Network.AMQP.Utils.Helpers
15 import Network.AMQP.Utils.Options
16 import Paths_amqp_utils (version)
17 import System.Environment
25 args <- getArgs >>= parseargs 'p'
27 (printparam "rpc_timeout" [show (rpc_timeout args), "s"])
28 (error $ "invalid rpc_timeout")
29 printparam "client version" ["amqp-utils", showVersion version]
30 printparam "routing key" $ rKey args
31 (conn, chan) <- connect args
32 addChannelExceptionHandler chan (X.throwTo tid)
33 (q, _, _) <- declareQueue chan newQueue {queueExclusive = True}
34 if (currentExchange args /= "")
36 printparam "exchange" $ currentExchange args
37 bindQueue chan q (T.pack $ currentExchange args) q
39 let inputFile' = firstInputFile (inputFiles args)
40 printparam "input file" $ inputFile'
44 else BL.readFile (inputFile')
45 printparam "output file" $ outputFile args
47 if outputFile args == "-"
49 else openBinaryFile (outputFile args) WriteMode
50 ctag <- consumeMsgs chan q NoAck (rpcClientCallback h tid args)
51 printparam "consumer tag" ctag
52 now <- getCurrentTime >>= return . floor . utcTimeToPOSIXSeconds
53 hr "publishing request"
57 (T.pack $ currentExchange args)
62 , msgCorrelationID = corrid args
63 , msgExpiration = msgexp args
64 , msgTimestamp = Just now
65 , msgHeaders = msgheader args
67 hr "waiting for answer"
70 (threadDelay (floor (1000000 * rpc_timeout args)) >>
71 throwTo tid TimeoutException)
73 (forever $ threadDelay 200000)
75 ec <- exceptionHandler x
76 hr "closing connection"
78 printparam "exiting" ec
81 exceptionHandler :: RpcException -> IO (ExitCode)
82 exceptionHandler ReceivedException = hr "success" >> (return ExitSuccess)
83 exceptionHandler TimeoutException = hr "timeout" >> (return $ ExitFailure 1)
85 rpcClientCallback :: Handle -> ThreadId -> Args -> (Message, Envelope) -> IO ()
86 rpcClientCallback h tid a m@(_, env) = do
87 let numstring = show $ envDeliveryTag env
88 hr $ "received " ++ numstring
92 (printmsg (Just h) m (anRiss a) now)
93 (\x -> X.throwTo tid (x :: X.IOException) >> return ([], []))
94 throwTo tid ReceivedException
101 instance X.Exception RpcException