module Mongrel2
( Handler
, ConnectedHandler
, mkHandler
, withConnectedHandler
, receiveRequest
, sendReply
, buildResponse
, ClientID
, Connection(..)
, Request(..)
, UUID
) where
import Blaze.ByteString.Builder (Builder)
import Data.Attoparsec
import Mongrel2.Types (Connection(..), Request(..))
import Mongrel2.Parser (messageParser, UUID, ClientID)
import Mongrel2.Response (buildResponse, mkResponse)
import qualified System.ZMQ as ZMQ
data Handler = Handler { handlerPullFrom :: String
, handlerPublishTo :: String
, handlerId :: Maybe String
}
data ConnectedHandler = ConnectedHandler { chPullSocket :: ZMQ.Socket ZMQ.Pull
, chPublishSocket :: ZMQ.Socket ZMQ.Pub
}
mkHandler :: String -> String -> Maybe String -> Handler
mkHandler = Handler
withConnectedHandler :: Handler -> (ConnectedHandler -> IO a) -> IO a
withConnectedHandler h io =
ZMQ.withContext 1 $ \c ->
ZMQ.withSocket c ZMQ.Pull $ \s -> do
ZMQ.withSocket c ZMQ.Pub $ \ps -> do
ZMQ.connect s $ handlerPullFrom h
ZMQ.connect ps $ handlerPublishTo h
case handlerId h of
Nothing -> return ()
Just uuid -> ZMQ.setOption ps $ ZMQ.Identity uuid
io $ ConnectedHandler s ps
receiveRequest :: ConnectedHandler -> IO (Connection,Request)
receiveRequest handler = do
msg <- ZMQ.receive (chPullSocket handler) []
case parseOnly messageParser msg of
Left errMsg ->
fail $ "Couldn't parse message: " ++ (show errMsg)
Right m -> do
return m
sendReply :: ConnectedHandler -> UUID -> [ClientID] -> Builder -> IO ()
sendReply handler uuid clientIds replyBuilder = do
let response = mkResponse uuid clientIds replyBuilder
ZMQ.send (chPublishSocket handler) response []