packages feed

c10k 0.2.0 → 0.3.0

raw patch · 3 files changed

+104/−23 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.C10kServer: runC10kServerH :: C10kServerH -> C10kConfig -> IO ()
+ Network.C10kServer: type C10kServerH = Handle -> TCPInfo -> IO ()
+ Network.TCPInfo: TCPInfo :: HostName -> ServiceName -> HostName -> ServiceName -> TCPInfo
+ Network.TCPInfo: accept :: Socket -> IO (Handle, TCPInfo)
+ Network.TCPInfo: data TCPInfo
+ Network.TCPInfo: instance Eq TCPInfo
+ Network.TCPInfo: instance Show TCPInfo
+ Network.TCPInfo: myAddr :: TCPInfo -> HostName
+ Network.TCPInfo: myPort :: TCPInfo -> ServiceName
+ Network.TCPInfo: peerAddr :: TCPInfo -> HostName
+ Network.TCPInfo: peerPort :: TCPInfo -> ServiceName

Files

Network/C10kServer.hs view
@@ -16,15 +16,21 @@   (e.g. @kill `cat PIDFILE`@ where the PID file name is   specified by 'pidFile') -}-module Network.C10kServer (C10kServer, C10kConfig(..),-                           runC10kServer) where+module Network.C10kServer (+    C10kConfig(..)+  , C10kServer,  runC10kServer+  , C10kServerH, runC10kServerH+  ) where  import Control.Concurrent import Control.Exception import Control.Monad+import IO hiding (catch, try) import Network hiding (accept) import Network.Socket import Prelude hiding (catch)+import Network.TCPInfo hiding (accept)+import qualified Network.TCPInfo as T (accept) import System.Posix.Process import System.Posix.Signals import System.Posix.User@@ -38,6 +44,11 @@ type C10kServer = Socket -> IO ()  {-|+  The type of the first argument of 'runC10kServerH'.+-}+type C10kServerH = Handle -> TCPInfo -> IO ()++{-|   The type of configuration given to 'runC10kServer' as the second   argument. -}@@ -81,9 +92,22 @@   Run 'C10kServer' with 'C10kConfig'. -} runC10kServer :: C10kServer -> C10kConfig -> IO ()-runC10kServer srv cnf = do+runC10kServer srv cnf = runC10kServer' (dispatchS srv) cnf++----------------------------------------------------------------++{-|+  Run 'C10kServerH' with 'C10kConfig'.+-}+runC10kServerH :: C10kServerH -> C10kConfig -> IO ()+runC10kServerH srv cnf = runC10kServer' (dispatchH srv) cnf++----------------------------------------------------------------++runC10kServer' :: (Socket -> Dispatch) -> C10kConfig -> IO ()+runC10kServer' sDispatch cnf = do     initHook cnf `catch` ignore-    initServer srv cnf `catch` errorHandle+    initServer sDispatch cnf `catch` errorHandle     parentStartedHook cnf `catch` ignore     doNothing   where@@ -97,14 +121,14 @@  ---------------------------------------------------------------- -initServer :: C10kServer -> C10kConfig -> IO ()-initServer srv cnf = do+initServer :: (Socket -> Dispatch) -> C10kConfig -> IO ()+initServer sDispatch cnf = do     let port = Service $ portName cnf         n    = preforkProcessNumber cnf         pidf = pidFile cnf     s <- listenOn port     setGroupUser-    preFork s n srv cnf+    preFork n (sDispatch s) cnf     sClose s     writePidFile pidf   where@@ -117,11 +141,11 @@         getGroupEntryForName (group cnf) >>= setGroupID . groupID         getUserEntryForName (user cnf) >>= setUserID . userID -preFork :: Socket -> Int -> C10kServer -> C10kConfig -> IO ()-preFork s n srv cnf = do+preFork :: Int -> Dispatch -> C10kConfig -> IO ()+preFork n dispatch cnf = do     ignoreSigChild     pid <- getProcessID-    cids <- replicateM n $ forkProcess (runServer s srv cnf)+    cids <- replicateM n $ forkProcess (runServer dispatch cnf)     mapM_ (terminator pid cids) [sigTERM,sigINT]   where     ignoreSigChild = installHandler sigCHLD Ignore Nothing@@ -133,30 +157,42 @@  ---------------------------------------------------------------- -runServer :: Socket -> C10kServer -> C10kConfig -> IO ()-runServer s srv cnf = do+runServer :: Dispatch -> C10kConfig -> IO ()+runServer dispatch cnf = do     startedHook cnf     mvar <- newMVar 0-    dispatchOrSleep mvar s srv cnf+    dispatchOrSleep mvar dispatch cnf -dispatchOrSleep :: MVar Int -> Socket -> C10kServer -> C10kConfig -> IO ()-dispatchOrSleep mvar s srv cnf = do+dispatchOrSleep :: MVar Int -> Dispatch -> C10kConfig -> IO ()+dispatchOrSleep mvar dispatch cnf = do     n <- howMany     if n > threadNumberPerProcess cnf         then sleep (sleepTimer cnf * microseconds)-        else dispatch-    dispatchOrSleep mvar s srv cnf+        else dispatch increase decrease+    dispatchOrSleep mvar dispatch cnf   where-    dispatch = do-        (sock,_) <- accept s-        increase-        forkIO $ srv sock `finally` (decrease >> (sClose sock `catch` ignore))-        return ()     howMany = readMVar mvar     increase = modifyMVar_ mvar (return . succ)     decrease = modifyMVar_ mvar (return . pred)     sleep = threadDelay +----------------------------------------------------------------++type Dispatch = IO () -> IO () -> IO ()++dispatchS :: C10kServer -> Socket -> Dispatch+dispatchS srv sock inc dec = do+    (connsock,_) <- accept sock+    inc+    forkIO $ srv connsock `finally` (dec >> sClose connsock)+    return ()++dispatchH :: C10kServerH -> Socket -> Dispatch+dispatchH srv sock inc dec = do+    (hdl,tcpi) <- T.accept sock+    inc+    forkIO $ srv hdl tcpi `finally` (dec >> hClose hdl)+    return ()  ---------------------------------------------------------------- 
+ Network/TCPInfo.hs view
@@ -0,0 +1,44 @@+{-|+  Yet another accept() to tell TCP information.+-}+module Network.TCPInfo where++import Data.List+import Network.Socket+import System.IO++{-|+  A Type to carry TCP information.+-}+data TCPInfo = TCPInfo {+  -- | Local IP address+    myAddr :: HostName+  -- | Local port number+  , myPort :: ServiceName+  -- | Remote IP address+  , peerAddr :: HostName+  -- | Remote port number+  , peerPort :: ServiceName+  } deriving (Eq,Show)++----------------------------------------------------------------++{-|+  Yet another accept() to return both 'Handle' and 'TCPInfo'.+-}+accept :: Socket -> IO (Handle, TCPInfo)+accept sock = do+    (sock', sockaddr) <- Network.Socket.accept sock+    let getInfo = getNameInfo [NI_NUMERICHOST, NI_NUMERICSERV] True True+    (Just vMyAddr,   Just vMyPort)   <- getSocketName sock' >>= getInfo+    (Just vPeerAddr, Just vPeerPort) <- getInfo sockaddr+    hdl <- socketToHandle sock' ReadWriteMode+    let info = TCPInfo { myAddr = strip vMyAddr+                       , myPort = vMyPort+                       , peerAddr = strip vPeerAddr+                       , peerPort = vPeerPort}+    return (hdl, info)+  where+    strip x+      | "::ffff:" `isPrefixOf` x = drop 7 x+      | otherwise                = x
c10k.cabal view
@@ -1,5 +1,5 @@ Name:                   c10k-Version:                0.2.0+Version:                0.3.0 Author:                 Kazu Yamamoto <kazu@iij.ad.jp> Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp> License:                BSD3@@ -21,6 +21,7 @@ Library   GHC-Options:          -Wall -O2   Exposed-Modules:      Network.C10kServer+                        Network.TCPInfo   Build-Depends:        base >= 4 && < 10, haskell98, network, unix, hdaemonize Source-Repository head   Type:                 git