improve more handling of errors when starting server
+ add shutdown method to server (and dispatcher)
This commit is contained in:
parent
dec286460d
commit
d3fc01689f
@ -82,6 +82,7 @@ class Dispatcher:
|
||||
self._subscriptions = {}
|
||||
self._lock = threading.RLock()
|
||||
self.restart = srv.restart
|
||||
self.shutdown = srv.shutdown
|
||||
|
||||
def broadcast_event(self, msg, reallyall=False):
|
||||
"""broadcasts a msg to all active connections
|
||||
|
@ -29,6 +29,7 @@ import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
from collections import OrderedDict
|
||||
|
||||
from secop.errors import ConfigError, SECoPError
|
||||
@ -219,6 +220,10 @@ class Server:
|
||||
self._restart = True
|
||||
self.interface.shutdown()
|
||||
|
||||
def shutdown(self):
|
||||
self._restart = False
|
||||
self.interface.shutdown()
|
||||
|
||||
def _processCfg(self):
|
||||
errors = []
|
||||
opts = dict(self.node_cfg)
|
||||
@ -227,31 +232,39 @@ class Server:
|
||||
if opts:
|
||||
errors.append(self.unknown_options(cls, opts))
|
||||
self.modules = OrderedDict()
|
||||
badclass = None
|
||||
failure_traceback = None # traceback for the last error
|
||||
failed = set() # python modules failed to load
|
||||
self.lastError = None
|
||||
for modname, options in self.module_cfg.items():
|
||||
opts = dict(options)
|
||||
pymodule = None
|
||||
try:
|
||||
classname = opts.pop('class')
|
||||
pymodule = classname.rpartition('.')[0]
|
||||
if pymodule in failed:
|
||||
continue
|
||||
cls = get_class(classname)
|
||||
modobj = cls(modname, self.log.getChild(modname), opts, self)
|
||||
# all used args should be popped from opts!
|
||||
if opts:
|
||||
errors.append(self.unknown_options(cls, opts))
|
||||
self.modules[modname] = modobj
|
||||
except ConfigError as e:
|
||||
errors.append(str(e))
|
||||
except Exception as e:
|
||||
if str(e) == 'no such class':
|
||||
errors.append('%s not found' % classname)
|
||||
if pymodule is None:
|
||||
if str(e) == 'no such class':
|
||||
errors.append('%s not found' % classname)
|
||||
else:
|
||||
raise
|
||||
errors.append(repr(e))
|
||||
else:
|
||||
failed.add(pymodule)
|
||||
badclass = classname
|
||||
errors.append('error importing %s' % pymodule)
|
||||
failure_traceback = traceback.format_exc()
|
||||
errors.append('error importing %s' % classname)
|
||||
else:
|
||||
try:
|
||||
modobj = cls(modname, self.log.getChild(modname), opts, self)
|
||||
# all used args should be popped from opts!
|
||||
if opts:
|
||||
errors.append(self.unknown_options(cls, opts))
|
||||
self.modules[modname] = modobj
|
||||
except Exception as e:
|
||||
failure_traceback = traceback.format_exc()
|
||||
errors.append('error creating %s: %r' % (modname, e))
|
||||
|
||||
poll_table = dict()
|
||||
# all objs created, now start them up and interconnect
|
||||
@ -276,7 +289,11 @@ class Server:
|
||||
|
||||
# call init on each module after registering all
|
||||
for modname, modobj in self.modules.items():
|
||||
modobj.initModule()
|
||||
try:
|
||||
modobj.initModule()
|
||||
except Exception as e:
|
||||
failure_traceback = traceback.format_exc()
|
||||
errors.append('error initializing %s: %r' % (modname, e))
|
||||
|
||||
if errors:
|
||||
for errtxt in errors:
|
||||
@ -285,9 +302,8 @@ class Server:
|
||||
# print a list of config errors to stderr
|
||||
sys.stderr.write('\n'.join(errors))
|
||||
sys.stderr.write('\n')
|
||||
if badclass:
|
||||
# force stack trace for import of last erroneous module
|
||||
get_class(badclass)
|
||||
if failure_traceback:
|
||||
sys.stderr.write(failure_traceback)
|
||||
sys.exit(1)
|
||||
|
||||
if self._testonly:
|
||||
|
Loading…
x
Reference in New Issue
Block a user