option to continue running if binds fail

This commit is contained in:
ed 2021-10-18 20:24:11 +02:00
parent a033388d2b
commit 23c8d3d045
3 changed files with 34 additions and 8 deletions

View file

@ -381,6 +381,10 @@ def run_argparse(argv, formatter):
ap2.add_argument("--no-readme", action="store_true", help="disable rendering readme.md into directory listings")
ap2.add_argument("--vague-403", action="store_true", help="send 404 instead of 403 (security through ambiguity, very enterprise)")
ap2 = ap.add_argument_group('yolo options')
ap2.add_argument("--ign-ebind", action="store_true", help="continue running even if it's impossible to listen on some of the requested endpoints")
ap2.add_argument("--ign-ebind-all", action="store_true", help="continue running even if it's impossible to receive connections at all")
ap2 = ap.add_argument_group('logging options')
ap2.add_argument("-q", action="store_true", help="quiet")
ap2.add_argument("-lo", metavar="PATH", type=u, help="logfile, example: cpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz")

View file

@ -38,6 +38,7 @@ class SvcHub(object):
self.stop_req = False
self.stopping = False
self.stop_cond = threading.Condition()
self.retcode = 0
self.httpsrv_up = 0
self.log_mutex = threading.Lock()
@ -59,9 +60,9 @@ class SvcHub(object):
if not args.no_fpool and args.j != 1:
m = "WARNING: --use-fpool combined with multithreading is untested and can probably cause undefined behavior"
if ANYWIN:
m = "windows cannot do multithreading without --no-fpool, so enabling that -- note that upload performance will suffer if you have microsoft defender \"real-time protection\" enabled, so you probably want to use -j 1 instead"
m = 'windows cannot do multithreading without --no-fpool, so enabling that -- note that upload performance will suffer if you have microsoft defender "real-time protection" enabled, so you probably want to use -j 1 instead'
args.no_fpool = True
self.log("root", m, c=3)
# initiate all services to manage
@ -98,14 +99,23 @@ class SvcHub(object):
def thr_httpsrv_up(self):
time.sleep(5)
failed = self.broker.num_workers - self.httpsrv_up
expected = self.broker.num_workers * self.tcpsrv.nsrv
failed = expected - self.httpsrv_up
if not failed:
return
m = "{}/{} workers failed to start"
m = m.format(failed, self.broker.num_workers)
m = m.format(failed, expected)
self.log("root", m, 1)
os._exit(1)
if self.args.ign_ebind_all:
return
if self.args.ign_ebind and self.tcpsrv.srv:
return
self.retcode = 1
os.kill(os.getpid(), signal.SIGTERM)
def cb_httpsrv_up(self):
self.httpsrv_up += 1
@ -242,7 +252,7 @@ class SvcHub(object):
print("waiting for thumbsrv (10sec)...")
print("nailed it", end="")
ret = 0
ret = self.retcode
finally:
print("\033[0m")
if self.logf:

View file

@ -42,9 +42,21 @@ class TcpSrv(object):
self.log("tcpsrv", m)
self.srv = []
self.nsrv = 0
for ip in self.args.i:
for port in self.args.p:
self.srv.append(self._listen(ip, port))
self.nsrv += 1
try:
self._listen(ip, port)
except Exception as ex:
if self.args.ign_ebind or self.args.ign_ebind_all:
m = "could not listen on {}:{}: {}"
self.log("tcpsrv", m.format(ip, port, ex), c=1)
else:
raise
if not self.srv and not self.args.ign_ebind_all:
raise Exception("could not listen on any of the given interfaces")
def _listen(self, ip, port):
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -52,7 +64,7 @@ class TcpSrv(object):
srv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
try:
srv.bind((ip, port))
return srv
self.srv.append(srv)
except (OSError, socket.error) as ex:
if ex.errno in [98, 48]:
e = "\033[1;31mport {} is busy on interface {}\033[0m".format(port, ip)