def run(): """ Entry point into background worker process. This wires up stuff such that a WorkerProcess instance is talking WAMP over stdio to the node controller. """ ## create the top-level parser ## import argparse parser = argparse.ArgumentParser() parser.add_argument('-d', '--debug', action = 'store_true', help = 'Debug on.') parser.add_argument('--reactor', default = None, choices = ['select', 'poll', 'epoll', 'kqueue', 'iocp'], help = 'Explicit Twisted reactor selection') parser.add_argument('--cbdir', type = str, default = None, help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)") parser.add_argument('-n', '--name', default = None, help = 'Optional process name to set.') options = parser.parse_args() ## make sure logging to something else than stdio is setup _first_ ## from crossbar.twisted.process import BareFormatFileLogObserver flo = BareFormatFileLogObserver(sys.stderr) log.startLoggingWithObserver(flo.emit) ## the worker's PID ## pid = os.getpid() try: import setproctitle except ImportError: log.msg("Warning, could not set process title (setproctitle not installed)") else: ## set process title if requested to ## if options.name: setproctitle.setproctitle(options.name) else: setproctitle.setproctitle("Crossbar.io Worker") ## Crossbar.io node directory ## if hasattr(options, 'cbdir') and not options.cbdir: if os.environ.has_key("CROSSBAR_DIR"): options.cbdir = os.environ['CROSSBAR_DIR'] else: options.cbdir = '.crossbar' options.cbdir = os.path.abspath(options.cbdir) log.msg("Starting from node directory {}.".format(options.cbdir)) ## we use an Autobahn utility to import the "best" available Twisted reactor ## from autobahn.twisted.choosereactor import install_reactor reactor = install_reactor(options.reactor) from twisted.python.reflect import qual log.msg("Running on {} reactor.".format(qual(reactor.__class__).split('.')[-1])) from autobahn.twisted.websocket import WampWebSocketServerProtocol class WorkerServerProtocol(WampWebSocketServerProtocol): def connectionLost(self, reason): try: log.msg("Connection to node controller lost.") WampWebSocketServerProtocol.connectionLost(self, reason) except: pass finally: ## loosing the connection to the node controller (the pipes) is fatal. ## stop the reactor and exit with error if reactor.running: reactor.addSystemEventTrigger('after', 'shutdown', os._exit, 1) reactor.stop() else: sys.exit(1) try: ## create a WAMP application session factory ## from autobahn.twisted.wamp import ApplicationSessionFactory session_factory = ApplicationSessionFactory() session_factory.options = options session_factory.session = WorkerProcess ## create a WAMP-over-WebSocket transport server factory ## from autobahn.twisted.websocket import WampWebSocketServerFactory transport_factory = WampWebSocketServerFactory(session_factory, "ws://localhost", debug = False) transport_factory.protocol = WorkerServerProtocol transport_factory.setProtocolOptions(failByDrop = False) ## create a protocol instance and wire up to stdio ## from twisted.internet import stdio proto = transport_factory.buildProtocol(None) stdio.StandardIO(proto) ## now start reactor loop ## log.msg("Entering event loop ..") #reactor.callLater(4, reactor.stop) reactor.run() except Exception as e: log.msg("Unhandled exception - {}".format(e)) if reactor.running: reactor.addSystemEventTrigger('after', 'shutdown', os._exit, 1) reactor.stop() else: sys.exit(1)
def run(): """ Entry point into background worker process. This wires up stuff such that a WorkerProcess instance is talking WAMP over stdio to the node controller. """ ## create the top-level parser ## import argparse parser = argparse.ArgumentParser() parser.add_argument('-d', '--debug', action = 'store_true', help = 'Debug on.') parser.add_argument('--reactor', default = None, choices = ['select', 'poll', 'epoll', 'kqueue', 'iocp'], help = 'Explicit Twisted reactor selection') parser.add_argument('--cbdir', type = str, default = None, help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)") parser.add_argument('-l', '--logfile', default = None, help = 'Log to log file instead of stderr.') options = parser.parse_args() ## make sure logging to something else than stdio is setup _first_ ## if options.logfile: log.startLogging(open(options.logfile, 'a')) else: log.startLogging(sys.stderr) pid = os.getpid() ## Crossbar.io node directory ## if hasattr(options, 'cbdir') and not options.cbdir: if os.environ.has_key("CROSSBAR_DIR"): options.cbdir = os.environ['CROSSBAR_DIR'] else: options.cbdir = '.crossbar' options.cbdir = os.path.abspath(options.cbdir) ## we use an Autobahn utility to import the "best" available Twisted reactor ## from autobahn.twisted.choosereactor import install_reactor reactor = install_reactor(options.reactor) ## from twisted.python.reflect import qual log.msg("Worker {}: starting at node directory {} on {} ..".format(pid, options.cbdir, qual(reactor.__class__).split('.')[-1])) try: ## create a WAMP application session factory ## from autobahn.twisted.wamp import ApplicationSessionFactory session_factory = ApplicationSessionFactory() session_factory.options = options session_factory.session = WorkerProcess ## create a WAMP-over-WebSocket transport server factory ## from autobahn.twisted.websocket import WampWebSocketServerFactory transport_factory = WampWebSocketServerFactory(session_factory, "ws://localhost", debug = False) transport_factory.setProtocolOptions(failByDrop = False) ## create a protocol instance and wire up to stdio ## from twisted.internet import stdio proto = transport_factory.buildProtocol(None) stdio.StandardIO(proto) ## now start reactor loop ## log.msg("Worker {}: entering event loop ..".format(pid)) reactor.run() except Exception as e: log.msg("Worker {}: Unhandled exception - {}".format(pid, e)) raise e sys.exit(1)