hsrelp 0.1.0.1 → 0.1.1.1
raw patch · 2 files changed
+30/−15 lines, 2 filesdep +network-bsddep ~attoparsecdep ~bytestringdep ~networkPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: network-bsd
Dependency ranges changed: attoparsec, bytestring, network, utf8-string
API changes (from Hackage documentation)
- Network.RELP.Server: type RelpMessageHandler = SockAddr Client connection address -> ByteString Log message -> IO Bool Reject message (reply error RSP) if False
+ Network.RELP.Server: type RelpMessageHandler = -- | Client connection address SockAddr -> -- | Log message ByteString -> -- | Reject message (reply error RSP) if False IO Bool
Files
- hsrelp.cabal +6/−6
- src/Network/RELP/Server.hs +24/−9
hsrelp.cabal view
@@ -1,5 +1,5 @@ name: hsrelp-version: 0.1.0.1+version: 0.1.1.1 synopsis: RELP (Reliable Event Logging Protocol) server implementation description: The specification of the RELP protocol:@@ -11,7 +11,6 @@ license-file: LICENSE author: Denis Afonin <verrens@yandex.ru> maintainer: Denis Afonin <verrens@yandex.ru>-copyright: (c) 2016 Denis Afonin category: Network build-type: Simple -- extra-source-files: @@ -21,10 +20,11 @@ -- other-modules: -- other-extensions: build-depends: base >= 4 && < 5,- network,- bytestring,- utf8-string,- attoparsec+ attoparsec >= 0.14.4 && < 0.15,+ bytestring >= 0.11.5 && < 0.12,+ network >= 3.1.4 && < 3.2,+ network-bsd >= 2.8.1 && < 2.9,+ utf8-string >= 1.0.2 && < 1.1 hs-source-dirs: src default-language: Haskell2010 exposed-modules: Network.RELP.Server
src/Network/RELP/Server.hs view
@@ -22,6 +22,8 @@ import Data.List (lookup) import Control.Applicative import Control.Monad+import qualified Control.Exception as E+import Control.Concurrent (forkFinally) -- | Message handler callback. type RelpMessageHandler =@@ -48,15 +50,7 @@ runRelpServer :: PortNumber -- ^ Port to listen on -> RelpMessageHandler -- ^ Message handler -> IO () -- ^ Never returns-runRelpServer port cb = withSocketsDo $ do- sock <- socket AF_INET Stream defaultProtocol- setSocketOption sock ReuseAddr 1- bindSocket sock (SockAddrInet port iNADDR_ANY)- listen sock 3- handleConnection sock- sClose sock- where-+runRelpServer port cb = runTCPServer Nothing port handleConnection where handleConnection sock = do accept sock >>= forkIO . handleMessage handleConnection sock@@ -91,6 +85,27 @@ putStrLn ("ERROR: strange message command: " ++ show msg) relpNAck sock msg "unexpected message command" return False++ runTCPServer :: Maybe HostName -> PortNumber -> (Socket -> IO a) -> IO a+ runTCPServer mhost port server = withSocketsDo $ do+ addr <- resolve+ E.bracket (open addr) close loop+ where+ resolve = do+ let hints = defaultHints {+ addrFlags = [AI_PASSIVE]+ , addrSocketType = Stream+ }+ head <$> getAddrInfo (Just hints) mhost (Just $ show port)+ open addr = E.bracketOnError (openSocket addr) close $ \sock -> do+ setSocketOption sock ReuseAddr 1+ withFdSocket sock setCloseOnExecIfNeeded+ bind sock $ addrAddress addr+ listen sock 1024+ return sock+ loop sock = forever $ E.bracketOnError (accept sock) (close . fst)+ $ \(conn, _peer) -> void $+ forkFinally (server conn) (const $ gracefulClose conn 5000) relpParser :: Parser RelpMessage