class Application(object): def __init__(self, configuration: Configuration): self.__configuration = configuration self.logger = Logger(__file__) self.__event_loop = asyncio.get_event_loop() self.reactor = AsyncioSelectorReactor(eventloop=self.__event_loop) def run(self): build_information: BuildInformation = self.__configuration.build_information( ) return self.__initialize(name=build_information.name(), version=build_information.version()) def __initialize(self, name: str, version: str) -> None: self.logger.info("Starting {0} VER: {1}".format(name, version)) self.reactor.listenTCP( self.__configuration.port(), ServiceFactory(configuration=self.__configuration, event_loop=self.__event_loop)) asyncio.set_event_loop(self.__event_loop) self.reactor.callLater(seconds=5, f=get_client().start_up) self.reactor.run() async def _initializer(self, reactor: AsyncioSelectorReactor): reactor.listenTCP( self.__configuration.port(), ServiceFactory(configuration=self.__configuration, event_loop=asyncio.get_event_loop())) asyncio.get_event_loop().create_task(coro=get_client().start_up(), name="start-nats") reactor.run()
async def _initializer(self, reactor: AsyncioSelectorReactor): reactor.listenTCP( self.__configuration.port(), ServiceFactory(configuration=self.__configuration, event_loop=asyncio.get_event_loop())) asyncio.get_event_loop().create_task(coro=get_client().start_up(), name="start-nats") reactor.run()
class CompatibilityTests(unittest.TestCase): def setUp(self): self.saved_signals = save_signal_handlers() self.io_loop = IOLoop() self.io_loop.make_current() self.reactor = AsyncioSelectorReactor() def tearDown(self): self.reactor.disconnectAll() self.io_loop.clear_current() self.io_loop.close(all_fds=True) restore_signal_handlers(self.saved_signals) def start_twisted_server(self): class HelloResource(Resource): isLeaf = True def render_GET(self, request): return b"Hello from twisted!" site = Site(HelloResource()) port = self.reactor.listenTCP(0, site, interface='127.0.0.1') self.twisted_port = port.getHost().port def start_tornado_server(self): class HelloHandler(RequestHandler): def get(self): self.write("Hello from tornado!") app = Application([('/', HelloHandler)], log_function=lambda x: None) server = HTTPServer(app) sock, self.tornado_port = bind_unused_port() server.add_sockets([sock]) def run_reactor(self): # In theory, we can run the event loop through Tornado, # Twisted, or asyncio interfaces. However, since we're trying # to avoid installing anything as the global event loop, only # the twisted interface gets everything wired up correectly # without extra hacks. This method is a part of a # no-longer-used generalization that allowed us to test # different combinations. self.stop_loop = self.reactor.stop self.stop = self.reactor.stop self.reactor.run() def tornado_fetch(self, url, runner): client = AsyncHTTPClient() fut = client.fetch(url) fut.add_done_callback(lambda f: self.stop_loop()) runner() return fut.result() def twisted_fetch(self, url, runner): # http://twistedmatrix.com/documents/current/web/howto/client.html chunks = [] client = Agent(self.reactor) d = client.request(b'GET', utf8(url)) class Accumulator(Protocol): def __init__(self, finished): self.finished = finished def dataReceived(self, data): chunks.append(data) def connectionLost(self, reason): self.finished.callback(None) def callback(response): finished = Deferred() response.deliverBody(Accumulator(finished)) return finished d.addCallback(callback) def shutdown(failure): if hasattr(self, 'stop_loop'): self.stop_loop() elif failure is not None: # loop hasn't been initialized yet; try our best to # get an error message out. (the runner() interaction # should probably be refactored). try: failure.raiseException() except: logging.error('exception before starting loop', exc_info=True) d.addBoth(shutdown) runner() self.assertTrue(chunks) return b''.join(chunks) def twisted_coroutine_fetch(self, url, runner): body = [None] @gen.coroutine def f(): # This is simpler than the non-coroutine version, but it cheats # by reading the body in one blob instead of streaming it with # a Protocol. client = Agent(self.reactor) response = yield client.request(b'GET', utf8(url)) with warnings.catch_warnings(): # readBody has a buggy DeprecationWarning in Twisted 15.0: # https://twistedmatrix.com/trac/changeset/43379 warnings.simplefilter('ignore', category=DeprecationWarning) body[0] = yield readBody(response) self.stop_loop() self.io_loop.add_callback(f) runner() return body[0] def testTwistedServerTornadoClientReactor(self): self.start_twisted_server() response = self.tornado_fetch( 'http://127.0.0.1:%d' % self.twisted_port, self.run_reactor) self.assertEqual(response.body, b'Hello from twisted!') def testTornadoServerTwistedClientReactor(self): self.start_tornado_server() response = self.twisted_fetch( 'http://127.0.0.1:%d' % self.tornado_port, self.run_reactor) self.assertEqual(response, b'Hello from tornado!') def testTornadoServerTwistedCoroutineClientReactor(self): self.start_tornado_server() response = self.twisted_coroutine_fetch( 'http://127.0.0.1:%d' % self.tornado_port, self.run_reactor) self.assertEqual(response, b'Hello from tornado!')
class CompatibilityTests(unittest.TestCase): def setUp(self): self.saved_signals = save_signal_handlers() self.io_loop = IOLoop() self.io_loop.make_current() self.reactor = AsyncioSelectorReactor() def tearDown(self): self.reactor.disconnectAll() self.io_loop.clear_current() self.io_loop.close(all_fds=True) restore_signal_handlers(self.saved_signals) def start_twisted_server(self): class HelloResource(Resource): isLeaf = True def render_GET(self, request): return b"Hello from twisted!" site = Site(HelloResource()) port = self.reactor.listenTCP(0, site, interface="127.0.0.1") self.twisted_port = port.getHost().port def start_tornado_server(self): class HelloHandler(RequestHandler): def get(self): self.write("Hello from tornado!") app = Application([("/", HelloHandler)], log_function=lambda x: None) server = HTTPServer(app) sock, self.tornado_port = bind_unused_port() server.add_sockets([sock]) def run_reactor(self): # In theory, we can run the event loop through Tornado, # Twisted, or asyncio interfaces. However, since we're trying # to avoid installing anything as the global event loop, only # the twisted interface gets everything wired up correectly # without extra hacks. This method is a part of a # no-longer-used generalization that allowed us to test # different combinations. self.stop_loop = self.reactor.stop self.stop = self.reactor.stop self.reactor.run() def tornado_fetch(self, url, runner): client = AsyncHTTPClient() fut = client.fetch(url) fut.add_done_callback(lambda f: self.stop_loop()) runner() return fut.result() def twisted_fetch(self, url, runner): # http://twistedmatrix.com/documents/current/web/howto/client.html chunks = [] client = Agent(self.reactor) d = client.request(b"GET", utf8(url)) class Accumulator(Protocol): def __init__(self, finished): self.finished = finished def dataReceived(self, data): chunks.append(data) def connectionLost(self, reason): self.finished.callback(None) def callback(response): finished = Deferred() response.deliverBody(Accumulator(finished)) return finished d.addCallback(callback) def shutdown(failure): if hasattr(self, "stop_loop"): self.stop_loop() elif failure is not None: # loop hasn't been initialized yet; try our best to # get an error message out. (the runner() interaction # should probably be refactored). try: failure.raiseException() except: logging.error("exception before starting loop", exc_info=True) d.addBoth(shutdown) runner() self.assertTrue(chunks) return b"".join(chunks) def twisted_coroutine_fetch(self, url, runner): body = [None] @gen.coroutine def f(): # This is simpler than the non-coroutine version, but it cheats # by reading the body in one blob instead of streaming it with # a Protocol. client = Agent(self.reactor) response = yield client.request(b"GET", utf8(url)) with warnings.catch_warnings(): # readBody has a buggy DeprecationWarning in Twisted 15.0: # https://twistedmatrix.com/trac/changeset/43379 warnings.simplefilter("ignore", category=DeprecationWarning) body[0] = yield readBody(response) self.stop_loop() self.io_loop.add_callback(f) runner() return body[0] def testTwistedServerTornadoClientReactor(self): self.start_twisted_server() response = self.tornado_fetch( "http://127.0.0.1:%d" % self.twisted_port, self.run_reactor ) self.assertEqual(response.body, b"Hello from twisted!") def testTornadoServerTwistedClientReactor(self): self.start_tornado_server() response = self.twisted_fetch( "http://127.0.0.1:%d" % self.tornado_port, self.run_reactor ) self.assertEqual(response, b"Hello from tornado!") def testTornadoServerTwistedCoroutineClientReactor(self): self.start_tornado_server() response = self.twisted_coroutine_fetch( "http://127.0.0.1:%d" % self.tornado_port, self.run_reactor ) self.assertEqual(response, b"Hello from tornado!")