copy increase_rlimits.py from magic-wormhole-mailbox-server
This code was originally in magic-wormhole, embedded in the server startup code. I carved it out to a separate file (with tests) in mailbox-server, but it should be used here too.
This commit is contained in:
parent
9c44ee13cd
commit
f7b8c5b19a
35
src/wormhole_transit_relay/increase_rlimits.py
Normal file
35
src/wormhole_transit_relay/increase_rlimits.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
try:
|
||||||
|
# 'resource' is unix-only
|
||||||
|
from resource import getrlimit, setrlimit, RLIMIT_NOFILE
|
||||||
|
except ImportError: # pragma: nocover
|
||||||
|
getrlimit, setrlimit, RLIMIT_NOFILE = None, None, None # pragma: nocover
|
||||||
|
from twisted.python import log
|
||||||
|
|
||||||
|
def increase_rlimits():
|
||||||
|
if getrlimit is None:
|
||||||
|
log.msg("unable to import 'resource', leaving rlimit alone")
|
||||||
|
return
|
||||||
|
soft, hard = getrlimit(RLIMIT_NOFILE)
|
||||||
|
if soft >= 10000:
|
||||||
|
log.msg("RLIMIT_NOFILE.soft was %d, leaving it alone" % soft)
|
||||||
|
return
|
||||||
|
# OS-X defaults to soft=7168, and reports a huge number for 'hard',
|
||||||
|
# but won't accept anything more than soft=10240, so we can't just
|
||||||
|
# set soft=hard. Linux returns (1024, 1048576) and is fine with
|
||||||
|
# soft=hard. Cygwin is reported to return (256,-1) and accepts up to
|
||||||
|
# soft=3200. So we try multiple values until something works.
|
||||||
|
for newlimit in [hard, 10000, 3200, 1024]:
|
||||||
|
log.msg("changing RLIMIT_NOFILE from (%s,%s) to (%s,%s)" %
|
||||||
|
(soft, hard, newlimit, hard))
|
||||||
|
try:
|
||||||
|
setrlimit(RLIMIT_NOFILE, (newlimit, hard))
|
||||||
|
log.msg("setrlimit successful")
|
||||||
|
return
|
||||||
|
except ValueError as e:
|
||||||
|
log.msg("error during setrlimit: %s" % e)
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
log.msg("other error during setrlimit, leaving it alone")
|
||||||
|
log.err()
|
||||||
|
return
|
||||||
|
log.msg("unable to change rlimit, leaving it alone")
|
57
src/wormhole_transit_relay/test/test_rlimits.py
Normal file
57
src/wormhole_transit_relay/test/test_rlimits.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
from __future__ import print_function, unicode_literals
|
||||||
|
import mock
|
||||||
|
from twisted.trial import unittest
|
||||||
|
from ..increase_rlimits import increase_rlimits
|
||||||
|
|
||||||
|
class RLimits(unittest.TestCase):
|
||||||
|
def test_rlimit(self):
|
||||||
|
def patch_r(name, *args, **kwargs):
|
||||||
|
return mock.patch("wormhole_transit_relay.increase_rlimits." + name, *args, **kwargs)
|
||||||
|
fakelog = []
|
||||||
|
def checklog(*expected):
|
||||||
|
self.assertEqual(fakelog, list(expected))
|
||||||
|
fakelog[:] = []
|
||||||
|
NF = "NOFILE"
|
||||||
|
mock_NF = patch_r("RLIMIT_NOFILE", NF)
|
||||||
|
|
||||||
|
with patch_r("log.msg", fakelog.append):
|
||||||
|
with patch_r("getrlimit", None):
|
||||||
|
increase_rlimits()
|
||||||
|
checklog("unable to import 'resource', leaving rlimit alone")
|
||||||
|
|
||||||
|
with mock_NF:
|
||||||
|
with patch_r("getrlimit", return_value=(20000, 30000)) as gr:
|
||||||
|
increase_rlimits()
|
||||||
|
self.assertEqual(gr.mock_calls, [mock.call(NF)])
|
||||||
|
checklog("RLIMIT_NOFILE.soft was 20000, leaving it alone")
|
||||||
|
|
||||||
|
with patch_r("getrlimit", return_value=(10, 30000)) as gr:
|
||||||
|
with patch_r("setrlimit", side_effect=TypeError("other")):
|
||||||
|
with patch_r("log.err") as err:
|
||||||
|
increase_rlimits()
|
||||||
|
self.assertEqual(err.mock_calls, [mock.call()])
|
||||||
|
checklog("changing RLIMIT_NOFILE from (10,30000) to (30000,30000)",
|
||||||
|
"other error during setrlimit, leaving it alone")
|
||||||
|
|
||||||
|
for maxlimit in [40000, 20000, 9000, 2000, 1000]:
|
||||||
|
def setrlimit(which, newlimit):
|
||||||
|
if newlimit[0] > maxlimit:
|
||||||
|
raise ValueError("nope")
|
||||||
|
return None
|
||||||
|
calls = []
|
||||||
|
expected = []
|
||||||
|
for tries in [30000, 10000, 3200, 1024]:
|
||||||
|
calls.append(mock.call(NF, (tries, 30000)))
|
||||||
|
expected.append("changing RLIMIT_NOFILE from (10,30000) to (%d,30000)" % tries)
|
||||||
|
if tries > maxlimit:
|
||||||
|
expected.append("error during setrlimit: nope")
|
||||||
|
else:
|
||||||
|
expected.append("setrlimit successful")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
expected.append("unable to change rlimit, leaving it alone")
|
||||||
|
|
||||||
|
with patch_r("setrlimit", side_effect=setrlimit) as sr:
|
||||||
|
increase_rlimits()
|
||||||
|
self.assertEqual(sr.mock_calls, calls)
|
||||||
|
checklog(*expected)
|
Loading…
Reference in New Issue
Block a user