packages feed

snaplet-amqp 0.1.3.1 → 1.0.0.0

raw patch · 3 files changed

+83/−40 lines, 3 filesdep +bytestringdep +lensdep +resource-poolPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring, lens, resource-pool

API changes (from Hackage documentation)

- Snap.Snaplet.AMQP: amqpConn :: AmqpState -> AmqpC
- Snap.Snaplet.AMQP: class MonadIO m => HasAmqpConn m
- Snap.Snaplet.AMQP: getAmqpConn :: HasAmqpConn m => m AmqpC
- Snap.Snaplet.AMQP: instance HasAmqpConn (Handler b AmqpState)
- Snap.Snaplet.AMQP: instance MonadIO m => HasAmqpConn (ReaderT AmqpC m)
- Snap.Snaplet.AMQP: mkAmqpConn :: MonadIO m => Config -> m AmqpC
+ Snap.Snaplet.AMQP: amqpPool :: AmqpState -> AmqpPool
+ Snap.Snaplet.AMQP: class MonadIO m => HasAmqpPool m
+ Snap.Snaplet.AMQP: getAmqpPool :: HasAmqpPool m => m AmqpPool
+ Snap.Snaplet.AMQP: instance HasAmqpPool (Handler b AmqpState)
+ Snap.Snaplet.AMQP: instance MonadIO m => HasAmqpPool (ReaderT AmqpPool m)
+ Snap.Snaplet.AMQP: mkAmqpPool :: MonadIO m => Config -> m AmqpPool
- Snap.Snaplet.AMQP: AmqpState :: AmqpC -> AmqpState
+ Snap.Snaplet.AMQP: AmqpState :: AmqpPool -> AmqpState
- Snap.Snaplet.AMQP: runAmqp :: HasAmqpConn m => (AmqpC -> b) -> m b
+ Snap.Snaplet.AMQP: runAmqp :: HasAmqpPool m => ((Connection, Channel) -> b) -> m b

Files

README.org view
@@ -1,32 +1,71 @@ * Welcome!+  [[https://hackage.haskell.org/package/snaplet-amqp][https://img.shields.io/hackage/v/snaplet-amqp.svg?style=flat]]+  [[https://travis-ci.org/ixmatus/snaplet-amqp][https://travis-ci.org/ixmatus/snaplet-amqp.svg?branch=master]]+     =snaplet-amqp= provides a convenience interface to the Haskell AMQP   package.    #+BEGIN_SRC+  {-# LANGUAGE FlexibleInstances #-}+  {-# LANGUAGE OverloadedStrings #-}+  {-# LANGUAGE RecordWildCards   #-}+  {-# LANGUAGE TemplateHaskell   #-}++  module Main where++  ------------------------------------------------------------------------------   import           Control.Lens+  import           Data.ByteString.Char8 as C8+  import           Network.AMQP   import           Snap-  import           Snap.Snaplet   import           Snap.Snaplet.AMQP-  import Network.AMQP +  ------------------------------------------------------------------------------   data App = App-      { _amqp    :: Snaplet AmqpState }+      { _amqp :: Snaplet AmqpState+      }    makeLenses ''App -  instance HasAmqpConn (Handler b App) where-      getAmqpConn = with amqp getAmqpConn+  instance HasAmqpPool (Handler b App) where+      getAmqpPool = with amqp getAmqpPool +  ------------------------------------------------------------------------------+  -- | The application's routes.+  routes :: [(ByteString, Handler App App ())]+  routes = [ ("/"   , writeText "hello")+           , ("test", fooHandler)+           ]++  fooHandler :: Handler App App ()+  fooHandler = do+      let serverQueue = "myQueue"+          exchange'   = "myExchange"+          routingKey  = "myKey"++      _ <- runAmqp $ \(_, chan) -> do+          _ <- declareQueue chan newQueue {queueName = serverQueue}++          declareExchange chan newExchange { exchangeName = exchange'+                                           , exchangeType = "headers"+                                           }+          bindQueue chan serverQueue exchange' routingKey++          publishMsg chan exchange' routingKey+              newMsg {msgBody = "AMQP Snaplet!",+                      msgDeliveryMode = Just Persistent}++      modifyResponse $ setResponseCode 204+++  ------------------------------------------------------------------------------+  -- | The application initializer.   app :: SnapletInit App App   app = makeSnaplet "app" "An snaplet example application." Nothing $ do-      a <- nestSnaplet "amqp" amqp initAMQP-      addRoutes appRoutes -- Your routes, I haven't defined any here-      return $ App a--  handler = do-      runAmqp \(_, chan) -> do-        declareQueue chan newQueue {queueName = "myQueue"}-        declareExchange chan newExchange {exchangeName = "myExchange", exchangeType = "direct"}-        bindQueue chan "myQueue" "myExchange" "myKey"+      m <- nestSnaplet "amqp" amqp $ initAMQP+      addRoutes routes+      return $ App m +  main :: IO ()+  main = serveSnaplet defaultConfig app   #+END_SRC
snaplet-amqp.cabal view
@@ -1,5 +1,5 @@ Name:                snaplet-amqp-Version:             0.1.3.1+Version:             1.0.0.0 Synopsis:            Snap framework snaplet for the AMQP library Homepage:            https://github.com/ixmatus/snaplet-amqp License:             BSD3@@ -46,7 +46,10 @@   Build-Depends:     base                >= 4.4     && < 5,     snap                >= 0.13    && < 0.14,+    resource-pool       >= 0.2     && < 0.3,     amqp                >= 0.10    && < 0.11,+    bytestring          >= 0.9     && < 11,+    lens                >= 4       && < 5,     transformers        >= 0.4     && < 0.5,     configurator        >= 0.3     && < 0.4,     network             >= 2.5     && < 2.7,
src/Snap/Snaplet/AMQP.hs view
@@ -8,15 +8,16 @@ module Snap.Snaplet.AMQP   ( initAMQP   , runAmqp-  , mkAmqpConn+  , mkAmqpPool   , AmqpState   (..)-  , HasAmqpConn (..)+  , HasAmqpPool (..)   ) where  import           Control.Monad.State import           Control.Monad.Trans.Reader import           Data.Configurator import           Data.Configurator.Types+import           Data.Pool import           Network.AMQP               (Channel, Connection,                                              ConnectionOpts (..),                                              closeConnection,@@ -26,26 +27,26 @@ import           Snap.Snaplet  --------------------------------------------------------------------------------type AmqpC = (Connection, Channel)+type AmqpPool = Pool Connection -newtype AmqpState = AmqpState { amqpConn :: AmqpC }+newtype AmqpState = AmqpState { amqpPool :: AmqpPool }  --------------------------------------------------------------------------------class MonadIO m => HasAmqpConn m where-    getAmqpConn :: m AmqpC+class MonadIO m => HasAmqpPool m where+    getAmqpPool :: m AmqpPool -instance HasAmqpConn (Handler b AmqpState) where-    getAmqpConn = gets amqpConn+instance HasAmqpPool (Handler b AmqpState) where+    getAmqpPool = gets amqpPool -instance MonadIO m => HasAmqpConn (ReaderT AmqpC m) where-    getAmqpConn = ask+instance MonadIO m => HasAmqpPool (ReaderT AmqpPool m) where+    getAmqpPool = ask  -- | Initialize the AMQP Snaplet. initAMQP :: SnapletInit b AmqpState initAMQP = makeSnaplet "amqp" description datadir $ do-    c <- mkSnapletAmqpConn+    c <- mkSnapletAmqpPoolonn -    onUnload (closeConnection $ fst c)+    -- onUnload (closeConnection $ fst c)      return $ AmqpState c @@ -55,15 +56,15 @@  ------------------------------------------------------------------------------- -- | Constructs a connection in a snaplet context.-mkSnapletAmqpConn :: (MonadIO (m b v), MonadSnaplet m) => m b v AmqpC-mkSnapletAmqpConn = do+mkSnapletAmqpPoolonn :: (MonadIO (m b v), MonadSnaplet m) => m b v AmqpPool+mkSnapletAmqpPoolonn = do   conf <- getSnapletUserConfig-  mkAmqpConn conf+  mkAmqpPool conf  ------------------------------------------------------------------------------- -- | Constructs a connect from Config.-mkAmqpConn :: MonadIO m => Config -> m AmqpC-mkAmqpConn conf = do+mkAmqpPool :: MonadIO m => Config -> m AmqpPool+mkAmqpPool conf = do   host  <- liftIO $ require conf "host"   port  <- liftIO $ require conf "port"   vhost <- liftIO $ require conf "vhost"@@ -75,13 +76,13 @@                    , coVHost   = vhost                    , coAuth    = [plain login pass]                    }--  conn  <- liftIO $ openConnection'' connOpts-  chan  <- liftIO $ openChannel conn--  return (conn, chan)+  return =<< liftIO $ createPool (openConnection'' connOpts) closeConnection 1 30 10  ---------------------------------------------------------------------------------- | Runs an AMQP action in any monad with a HasAmqpConn instance.-runAmqp :: (HasAmqpConn m) => (AmqpC -> b) -> m b-runAmqp action = getAmqpConn >>= return . action+-- | Runs an AMQP action in any monad with a HasAmqpPoolonn instance.+runAmqp :: (HasAmqpPool m) => ((Connection, Channel) -> b) -> m b+runAmqp action = do+    pool <- getAmqpPool+    return =<< liftIO $ withResource pool $ \conn -> do+        chan <- openChannel conn+        return $ action (conn, chan)