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:
Romain GERARD 2020-01-04 13:28:36 +01:00
parent 0f1eb05216
commit df927db68e
3 changed files with 25 additions and 9 deletions

View file

@ -41,13 +41,15 @@ runSTDIOServer app = do
runTCPServer :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
runTCPServer endPoint@(host, port) app = do
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
runTCPClient :: (HostName, PortNumber) -> (N.AppData -> IO ()) -> IO ()
runTCPClient endPoint@(host, port) app = do
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

View file

@ -40,10 +40,15 @@ import qualified Credentials
rrunTCPClient :: N.ClientSettings -> (Connection -> IO a) -> IO a
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 ()))
(\(s, _) -> app Connection
{ read = Just <$> N.safeRecv s (N.getReadBufferSize cfg)
{ read = Just <$> N.safeRecv s defaultRecvBufferSize
, write = N.sendAll s
, close = N.close s
, rawConnection = Just s
@ -198,14 +203,16 @@ runTunnelingServer :: (HostName, PortNumber) -> ((ByteString, Int) -> Bool) -> I
runTunnelingServer endPoint@(host, port) isAllowed = do
info $ "WAIT for connection on " <> toStr endPoint
void $ N.runTCPServer (N.serverSettingsTCP (fromIntegral port) (fromString host)) $ \sClient ->
runApp (fromJust $ N.appRawSocket sClient) WS.defaultConnectionOptions (serverEventLoop isAllowed)
let srvSet = N.setReadBufferSize defaultRecvBufferSize $ N.serverSettingsTCP (fromIntegral port) (fromString host)
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"
where
runApp :: N.Socket -> WS.ConnectionOptions -> WS.ServerApp -> IO ()
runApp socket opts = bracket (WS.makePendingConnection socket opts)
runApp :: WS.Stream -> WS.ConnectionOptions -> WS.ServerApp -> IO ()
runApp socket opts = bracket (WS.makePendingConnectionFromStream socket opts)
(\conn -> catch (WS.close $ WS.pendingStream conn) (\(_ :: SomeException) -> return ()))
serverEventLoop :: ((ByteString, Int) -> Bool) -> WS.PendingConnection -> IO ()

View file

@ -2,7 +2,6 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StandaloneDeriving #-}
module Types where
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.WebSockets.Connection as WS
import System.IO.Unsafe (unsafeDupablePerformIO)
deriving instance Generic PortNumber
deriving instance Hashable PortNumber
@ -26,6 +26,13 @@ deriving instance Generic 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 StdioAppData = StdioAppData