diff --git a/amqp-worker.cabal b/amqp-worker.cabal
--- a/amqp-worker.cabal
+++ b/amqp-worker.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                amqp-worker
-version:             0.2.3
+version:             0.2.4
 synopsis:            High level functions for working with message queues
 description:         High level functions for working with message queues
 license:             BSD3
@@ -36,11 +36,24 @@
     , exceptions
     , data-default
     , monad-control
+    , monad-loops
     , mtl
     , resource-pool
     , split
     , text
     , transformers-base
+
+
+executable example
+  hs-source-dirs:      test
+  main-is:             Example.hs
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:       base
+                     , aeson
+                     , amqp-worker
+                     , exceptions
+                     , text
+  default-language:    Haskell2010
 
 
 test-suite test
diff --git a/src/Network/AMQP/Worker/Poll.hs b/src/Network/AMQP/Worker/Poll.hs
--- a/src/Network/AMQP/Worker/Poll.hs
+++ b/src/Network/AMQP/Worker/Poll.hs
@@ -5,12 +5,13 @@
 import Control.Concurrent (threadDelay)
 import Control.Monad.Trans.Control (MonadBaseControl)
 import Control.Monad.Base (liftBase)
+import Control.Monad.Loops (untilJust)
 
 poll :: (MonadBaseControl IO m) => Int -> m (Maybe a) -> m a
-poll us action = do
+poll us action = untilJust $ do
     ma <- action
     case ma of
-      Just a -> return a
+      Just a -> return $ Just a
       Nothing -> do
         liftBase $ threadDelay us
-        poll us action
+        return Nothing
diff --git a/test/Example.hs b/test/Example.hs
new file mode 100644
--- /dev/null
+++ b/test/Example.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Main where
+
+import Control.Monad.Catch (SomeException)
+import Data.Aeson (FromJSON, ToJSON)
+import Data.Text (Text)
+import GHC.Generics (Generic)
+import qualified Network.AMQP.Worker as Worker
+import Network.AMQP.Worker (fromURI, Exchange, Queue, Direct, def, WorkerException, Message(..), Connection)
+import System.IO (hSetBuffering, stdout, stderr, BufferMode(..))
+
+data TestMessage = TestMessage
+  { greeting :: Text }
+  deriving (Generic, Show, Eq)
+
+instance FromJSON TestMessage
+instance ToJSON TestMessage
+
+
+exchange :: Exchange
+exchange = Worker.exchange "testExchange"
+
+
+queue :: Queue Direct TestMessage
+queue = Worker.queue exchange "testQueue"
+
+
+results :: Queue Direct Text
+results = Worker.queue exchange "resultQueue"
+
+
+example :: IO ()
+example = do
+  -- connect
+  conn <- Worker.connect (fromURI "amqp://guest:guest@localhost:5672")
+
+  -- initialize the queues
+  Worker.initQueue conn queue
+  Worker.initQueue conn results
+
+  -- publish a message
+  Worker.publish conn queue (TestMessage "hello world")
+
+  -- create a worker, the program loops here
+  Worker.worker def conn queue onError (onMessage conn)
+
+
+onMessage :: Connection -> Message TestMessage -> IO ()
+onMessage conn m = do
+  let testMessage = value m
+  putStrLn "Got Message"
+  print testMessage
+  Worker.publish conn results (greeting testMessage)
+
+
+onError :: WorkerException SomeException -> IO ()
+onError e = do
+  putStrLn "Do something with errors"
+  print e
+
+
+
+main :: IO ()
+main = do
+  hSetBuffering stdout LineBuffering
+  hSetBuffering stderr LineBuffering
+  example
