Skip to content

Commit

Permalink
Some notes on config.
Browse files Browse the repository at this point in the history
  • Loading branch information
gregorycollins committed Nov 21, 2013
1 parent 85b89e8 commit 8a3fd26
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ TAGS
*.prof_*
*.aux
*.hp
.cabal-sandbox
cabal.sandbox.config
5 changes: 4 additions & 1 deletion src/Snap/Http/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ module Snap.Http.Server

------------------------------------------------------------------------------
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as S
import Data.Version (showVersion)
#ifndef PORTABLE
import System.Posix.Env
#endif
------------------------------------------------------------------------------
import qualified Paths_snap_server as V
import Snap.Core (MonadSnap (..), Snap)
import Snap.Http.Server.Config


------------------------------------------------------------------------------
-- | A short string describing the Snap server version
snapServerVersion :: ByteString
snapServerVersion = undefined
snapServerVersion = S.pack $! showVersion V.version


------------------------------------------------------------------------------
Expand Down
48 changes: 48 additions & 0 deletions src/Snap/Internal/Http/Server/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,54 @@ instance Show ConfigLog where
show (ConfigFileLog f) = "log to file " ++ show f
show (ConfigIoLog _) = "custom logging handler"


------------------------------------------------------------------------------
-- We should be using ServerConfig here. There needs to be a clearer
-- separation between:
--
-- * what the underlying code needs to configure itself
--
-- * what the command-line processing does.
--
-- The latter will provide "library" helper functions that operate on
-- ServerConfig/etc in order to allow users to configure their own environment.
--
--
-- Todo:
--
-- * need a function ::
-- CommandLineConfig -> IO [(ServerConfig hookState, AcceptFunc)]
--
-- this will prep for another function that will spawn all of the
-- accept loops with httpAcceptLoop.
--
-- * all backends provide "Some -> Foo -> Config -> IO AcceptFunc"
--
-- * add support for socket activation to command line, or delegate to
-- different library? It's linux-only anyways, need to ifdef. It would be
-- silly to depend on the socket-activation library for that one little
-- function.
--
-- * break config into multiple modules:
--
-- * everything that modifies the snap handler (compression, proxy
-- settings, error handler)
--
-- * everything that directly modifies server settings (hostname /
-- defaultTimeout / hooks / etc)
--
-- * everything that configures backends (port/bind/ssl*)
--
-- * everything that handles command line stuff
--
-- * utility stuff
--
-- Cruft that definitely must be removed:
--
-- * ConfigLog -- this becomes a binary option on the command-line side (no
-- logging or yes, to this file), but the ConfigIoLog gets zapped
-- altogether.

------------------------------------------------------------------------------
-- | A record type which represents partial configurations (for 'httpServe')
-- by wrapping all of its fields in a 'Maybe'. Values of this type are usually
Expand Down
3 changes: 3 additions & 0 deletions src/Snap/Internal/Http/Server/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ data EventLoopCpu = EventLoopCpu


------------------------------------------------------------------------------
-- | The main Snap webserver loop. Given a server handler, configuration, and a
-- function to accept new connections, runs an HTTP loop forever over N
-- threads, until a ThreadKilled exception is received.
httpAcceptLoop :: forall hookState .
ServerHandler hookState -- ^ server handler
-> ServerConfig hookState -- ^ server config
Expand Down
86 changes: 86 additions & 0 deletions tools/benchmark_shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/python
#
# This program is intended to be run via sudo, and does the following
# things:
#
# 1. Sets up a high-performance networking environment by tweaking
# various sysctl settings.
# 2. Runs either an interactive shell or a command line program.
# 3. Resets the environment back to what it was.

import os, sys, tempfile

sysctls = dict(
Darwin={
'kern.ipc.somaxconn': 1024,
'kern.maxfiles': 22528,
'kern.maxfilesperproc': 20480,
'net.inet.ip.portrange.first': 1024,
'net.inet.ip.portrange.hifirst': 1024,
},
Linux={
'net.core.somaxconn': 1024,
'net.core.rmem_max': 16777216,
'net.core.wmem_max': 16777216,
'net.ipv4.ip_local_port_range': '1024 65535',
'net.ipv4.tcp_fin_timeout': 15,
'net.ipv4.tcp_max_syn_backlog': 16384,
'net.ipv4.tcp_rmem': '4096 87380 16777216',
'net.ipv4.tcp_tw_recycle': 1,
'net.ipv4.tcp_tw_reuse': 1,
'net.ipv4.tcp_wmem': '4096 65536 16777216',
},
)

ulimits = dict(
Darwin={
'-n': 20480,
},
Linux={
'-n': 131072,
},
)

if os.access('/sbin/sysctl', os.X_OK):
sysctl = '/sbin/sysctl'
elif os.access('/usr/sbin/sysctl', os.X_OK):
sysctl = '/usr/sbin/sysctl'
else:
print >> sys.stderr, 'where is sysctl!?'
sys.exit(1)

changed_sysctls = {}

def change_sysctl(name, newval):
oldval = os.popen('%s -n %s' % (sysctl, name), 'r').read().strip().replace('\t', ' ')
if not oldval:
print >> sys.stderr, 'could not get value of ' + name
return
if oldval == str(newval):
return
ret = os.system('%s -w %s=%r 2>/dev/null' % (sysctl, name, newval))
if ret != 0:
print >> sys.stderr, 'could not change %s from %s to %r' % (name, oldval, newval)
return
changed_sysctls[name] = oldval

platform = os.uname()[0]

for (n,v) in sysctls[platform].iteritems():
change_sysctl(n,v)

fd, path = tempfile.mkstemp('.sh')

fp = os.fdopen(fd, 'w')
for (n, v) in ulimits[platform].iteritems():
print >> fp, 'ulimit %s %s' % (n, v)
if len(sys.argv) > 1:
print >> fp, 'exec ' + ' '.join(sys.argv[1:])
else:
print >> fp, 'exec %s -l' % os.environ.get('SHELL', '/bin/bash')
fp.close()
os.system('exec /bin/sh ' + path)
os.unlink(path)

for (n,v) in changed_sysctls.iteritems():
change_sysctl(n,v)

0 comments on commit 8a3fd26

Please sign in to comment.