Perf improvements: Use default os setting for socket recv buffer size
+ This commit 8e38589efb (diff-8c54fc2d40ad45803c6889efbb0192bbR278)
introduce a default fixed size read buffer which is too low for most modern system. Thus it induce a lot of unecessary syscall and cpu usage.
Use the default OS settings in order to let the user control it with
ie: /proc/sys/net/ipv4/tcp_rmem
Former-commit-id: 11329e7b2d39a571afcfa1c41b36ca43b8c6ee0c
Former-commit-id: d125be3860d756e8608707db387b9293005d02f8 [formerly cc16d8a3c00a1f2ae215b44b94356f0fd9b06abc] [formerly a4977ba6a35eb7805b01eb9b628786e22842f480 [formerly fd3d401b93d75acf5a20d37598cf115d234b47ad [formerly fd3d401b93d75acf5a20d37598cf115d234b47ad [formerly fd3d401b93d75acf5a20d37598cf115d234b47ad [formerly bec6f99d38ff1e9c53a0a7d71ae6051280508d2e]]]]]
Former-commit-id: 18d8b263236b960c37a41e63491bc287bf584a67 [formerly 9d2ab35501de57b0ba1ee8d18f1fb173a3ca98f6]
Former-commit-id: 00bdbc5e1cd318896a012b76dfdc68964434b43d
Former-commit-id: 86df02c0670359a2bb2429eae4b9b633f5d520ef
Former-commit-id: 59966a7acefbbdc76e580d281f8be7ee2ca1db03
Former-commit-id: d670c023b29c085d4e76809ec539fcd91d6be993 [formerly 2bfa1100e83fd689dd2e2c565fe0838036c1b588]
Former-commit-id: c7c40b2a4e933cbff27713a87d7cc701c1279d32
This commit is contained in:
parent
0f1eb05216
commit
df927db68e
3 changed files with 25 additions and 9 deletions
|
@ -41,13 +41,15 @@ runSTDIOServer app = do
|
||||||
runTCPServer :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
|
runTCPServer :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
|
||||||
runTCPServer endPoint@(host, port) app = do
|
runTCPServer endPoint@(host, port) app = do
|
||||||
info $ "WAIT for tcp connection on " <> toStr endPoint
|
info $ "WAIT for tcp connection on " <> toStr endPoint
|
||||||
void $ N.runTCPServer (N.serverSettingsTCP (fromIntegral port) (fromString host)) app
|
let srvSet = N.setReadBufferSize defaultRecvBufferSize $ N.serverSettingsTCP (fromIntegral port) (fromString host)
|
||||||
|
void $ N.runTCPServer srvSet app
|
||||||
info $ "CLOSE tcp server on " <> toStr endPoint
|
info $ "CLOSE tcp server on " <> toStr endPoint
|
||||||
|
|
||||||
runTCPClient :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
|
runTCPClient :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
|
||||||
runTCPClient endPoint@(host, port) app = do
|
runTCPClient endPoint@(host, port) app = do
|
||||||
info $ "CONNECTING to " <> toStr endPoint
|
info $ "CONNECTING to " <> toStr endPoint
|
||||||
void $ N.runTCPClient (N.clientSettingsTCP (fromIntegral port) (BC.pack host)) app
|
let srvSet = N.setReadBufferSize defaultRecvBufferSize $ N.clientSettingsTCP (fromIntegral port) (BC.pack host)
|
||||||
|
void $ N.runTCPClient srvSet app
|
||||||
info $ "CLOSE connection to " <> toStr endPoint
|
info $ "CLOSE connection to " <> toStr endPoint
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,15 @@ import qualified Credentials
|
||||||
|
|
||||||
rrunTCPClient :: N.ClientSettings -> (Connection -> IO a) -> IO a
|
rrunTCPClient :: N.ClientSettings -> (Connection -> IO a) -> IO a
|
||||||
rrunTCPClient cfg app = bracket
|
rrunTCPClient cfg app = bracket
|
||||||
(N.getSocketFamilyTCP (N.getHost cfg) (N.getPort cfg) (N.getAddrFamily cfg))
|
(do
|
||||||
|
(s,addr) <- N.getSocketFamilyTCP (N.getHost cfg) (N.getPort cfg) (N.getAddrFamily cfg)
|
||||||
|
N.setSocketOption s N.RecvBuffer defaultRecvBufferSize
|
||||||
|
N.setSocketOption s N.SendBuffer defaultSendBufferSize
|
||||||
|
return (s,addr)
|
||||||
|
)
|
||||||
(\r -> catch (N.close $ fst r) (\(_ :: SomeException) -> return ()))
|
(\r -> catch (N.close $ fst r) (\(_ :: SomeException) -> return ()))
|
||||||
(\(s, _) -> app Connection
|
(\(s, _) -> app Connection
|
||||||
{ read = Just <$> N.safeRecv s (N.getReadBufferSize cfg)
|
{ read = Just <$> N.safeRecv s defaultRecvBufferSize
|
||||||
, write = N.sendAll s
|
, write = N.sendAll s
|
||||||
, close = N.close s
|
, close = N.close s
|
||||||
, rawConnection = Just s
|
, rawConnection = Just s
|
||||||
|
@ -198,14 +203,16 @@ runTunnelingServer :: (HostName, PortNumber) -> ((ByteString, Int) -> Bool) -> I
|
||||||
runTunnelingServer endPoint@(host, port) isAllowed = do
|
runTunnelingServer endPoint@(host, port) isAllowed = do
|
||||||
info $ "WAIT for connection on " <> toStr endPoint
|
info $ "WAIT for connection on " <> toStr endPoint
|
||||||
|
|
||||||
void $ N.runTCPServer (N.serverSettingsTCP (fromIntegral port) (fromString host)) $ \sClient ->
|
let srvSet = N.setReadBufferSize defaultRecvBufferSize $ N.serverSettingsTCP (fromIntegral port) (fromString host)
|
||||||
runApp (fromJust $ N.appRawSocket sClient) WS.defaultConnectionOptions (serverEventLoop isAllowed)
|
void $ N.runTCPServer (srvSet) $ \sClient -> do
|
||||||
|
stream <- WS.makeStream (Just <$> N.appRead sClient) (N.appWrite sClient . toStrict . fromJust)
|
||||||
|
runApp stream WS.defaultConnectionOptions (serverEventLoop isAllowed)
|
||||||
|
|
||||||
info "CLOSE server"
|
info "CLOSE server"
|
||||||
|
|
||||||
where
|
where
|
||||||
runApp :: N.Socket -> WS.ConnectionOptions -> WS.ServerApp -> IO ()
|
runApp :: WS.Stream -> WS.ConnectionOptions -> WS.ServerApp -> IO ()
|
||||||
runApp socket opts = bracket (WS.makePendingConnection socket opts)
|
runApp socket opts = bracket (WS.makePendingConnectionFromStream socket opts)
|
||||||
(\conn -> catch (WS.close $ WS.pendingStream conn) (\(_ :: SomeException) -> return ()))
|
(\conn -> catch (WS.close $ WS.pendingStream conn) (\(_ :: SomeException) -> return ()))
|
||||||
|
|
||||||
serverEventLoop :: ((ByteString, Int) -> Bool) -> WS.PendingConnection -> IO ()
|
serverEventLoop :: ((ByteString, Int) -> Bool) -> WS.PendingConnection -> IO ()
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
{-# LANGUAGE DeriveGeneric #-}
|
{-# LANGUAGE DeriveGeneric #-}
|
||||||
{-# LANGUAGE StandaloneDeriving #-}
|
{-# LANGUAGE StandaloneDeriving #-}
|
||||||
|
|
||||||
|
|
||||||
module Types where
|
module Types where
|
||||||
|
|
||||||
import ClassyPrelude
|
import ClassyPrelude
|
||||||
|
@ -19,6 +18,7 @@ import qualified Network.Socket as N hiding (recv, recvFrom,
|
||||||
import qualified Network.Socket.ByteString as N
|
import qualified Network.Socket.ByteString as N
|
||||||
|
|
||||||
import qualified Network.WebSockets.Connection as WS
|
import qualified Network.WebSockets.Connection as WS
|
||||||
|
import System.IO.Unsafe (unsafeDupablePerformIO)
|
||||||
|
|
||||||
deriving instance Generic PortNumber
|
deriving instance Generic PortNumber
|
||||||
deriving instance Hashable PortNumber
|
deriving instance Hashable PortNumber
|
||||||
|
@ -26,6 +26,13 @@ deriving instance Generic N.SockAddr
|
||||||
deriving instance Hashable N.SockAddr
|
deriving instance Hashable N.SockAddr
|
||||||
|
|
||||||
|
|
||||||
|
defaultRecvBufferSize :: Int
|
||||||
|
defaultRecvBufferSize = unsafeDupablePerformIO $
|
||||||
|
bracket (N.socket N.AF_INET N.Stream 0) N.close (\sock -> N.getSocketOption sock N.RecvBuffer)
|
||||||
|
|
||||||
|
defaultSendBufferSize :: Int
|
||||||
|
defaultSendBufferSize = defaultRecvBufferSize
|
||||||
|
|
||||||
data Protocol = UDP | TCP | STDIO | SOCKS5 deriving (Show, Read, Eq)
|
data Protocol = UDP | TCP | STDIO | SOCKS5 deriving (Show, Read, Eq)
|
||||||
|
|
||||||
data StdioAppData = StdioAppData
|
data StdioAppData = StdioAppData
|
||||||
|
|
Loading…
Reference in a new issue